[Python-checkins] benchmarks: Issue #18586: Remove the need for make_perf3.sh

brett.cannon python-checkins at python.org
Fri Aug 23 19:31:35 CEST 2013


http://hg.python.org/benchmarks/rev/b868d0a9c5d7
changeset:   205:b868d0a9c5d7
user:        Brett Cannon <brett at python.org>
date:        Fri Aug 23 13:30:30 2013 -0400
summary:
  Issue #18586: Remove the need for make_perf3.sh

files:
  lib3/2to3/2to3                                                                              |     5 +
  lib3/2to3/HACKING                                                                           |    49 +
  lib3/2to3/README                                                                            |   255 +
  lib3/2to3/example.py                                                                        |   405 +
  lib3/2to3/lib2to3/Grammar.txt                                                               |   158 +
  lib3/2to3/lib2to3/Grammar3.3.2.final.0.pickle                                               |   Bin 
  lib3/2to3/lib2to3/Grammar3.4.0.alpha.1.pickle                                               |   Bin 
  lib3/2to3/lib2to3/PatternGrammar.txt                                                        |    28 +
  lib3/2to3/lib2to3/PatternGrammar3.3.2.final.0.pickle                                        |   Bin 
  lib3/2to3/lib2to3/PatternGrammar3.4.0.alpha.1.pickle                                        |   Bin 
  lib3/2to3/lib2to3/__init__.py                                                               |     1 +
  lib3/2to3/lib2to3/btm_matcher.py                                                            |   168 +
  lib3/2to3/lib2to3/btm_utils.py                                                              |   283 +
  lib3/2to3/lib2to3/fixer_base.py                                                             |   189 +
  lib3/2to3/lib2to3/fixer_util.py                                                             |   432 +
  lib3/2to3/lib2to3/fixes/__init__.py                                                         |     1 +
  lib3/2to3/lib2to3/fixes/fix_apply.py                                                        |    59 +
  lib3/2to3/lib2to3/fixes/fix_basestring.py                                                   |    14 +
  lib3/2to3/lib2to3/fixes/fix_buffer.py                                                       |    22 +
  lib3/2to3/lib2to3/fixes/fix_callable.py                                                     |    37 +
  lib3/2to3/lib2to3/fixes/fix_dict.py                                                         |   107 +
  lib3/2to3/lib2to3/fixes/fix_except.py                                                       |    93 +
  lib3/2to3/lib2to3/fixes/fix_exec.py                                                         |    40 +
  lib3/2to3/lib2to3/fixes/fix_execfile.py                                                     |    52 +
  lib3/2to3/lib2to3/fixes/fix_exitfunc.py                                                     |    72 +
  lib3/2to3/lib2to3/fixes/fix_filter.py                                                       |    76 +
  lib3/2to3/lib2to3/fixes/fix_funcattrs.py                                                    |    21 +
  lib3/2to3/lib2to3/fixes/fix_future.py                                                       |    22 +
  lib3/2to3/lib2to3/fixes/fix_getcwdu.py                                                      |    19 +
  lib3/2to3/lib2to3/fixes/fix_has_key.py                                                      |   110 +
  lib3/2to3/lib2to3/fixes/fix_idioms.py                                                       |   152 +
  lib3/2to3/lib2to3/fixes/fix_import.py                                                       |    99 +
  lib3/2to3/lib2to3/fixes/fix_imports.py                                                      |   145 +
  lib3/2to3/lib2to3/fixes/fix_imports2.py                                                     |    16 +
  lib3/2to3/lib2to3/fixes/fix_input.py                                                        |    26 +
  lib3/2to3/lib2to3/fixes/fix_intern.py                                                       |    46 +
  lib3/2to3/lib2to3/fixes/fix_isinstance.py                                                   |    52 +
  lib3/2to3/lib2to3/fixes/fix_itertools.py                                                    |    42 +
  lib3/2to3/lib2to3/fixes/fix_itertools_imports.py                                            |    56 +
  lib3/2to3/lib2to3/fixes/fix_long.py                                                         |    19 +
  lib3/2to3/lib2to3/fixes/fix_map.py                                                          |    91 +
  lib3/2to3/lib2to3/fixes/fix_metaclass.py                                                    |   228 +
  lib3/2to3/lib2to3/fixes/fix_methodattrs.py                                                  |    24 +
  lib3/2to3/lib2to3/fixes/fix_ne.py                                                           |    23 +
  lib3/2to3/lib2to3/fixes/fix_next.py                                                         |   103 +
  lib3/2to3/lib2to3/fixes/fix_nonzero.py                                                      |    21 +
  lib3/2to3/lib2to3/fixes/fix_numliterals.py                                                  |    28 +
  lib3/2to3/lib2to3/fixes/fix_operator.py                                                     |    99 +
  lib3/2to3/lib2to3/fixes/fix_paren.py                                                        |    44 +
  lib3/2to3/lib2to3/fixes/fix_print.py                                                        |    87 +
  lib3/2to3/lib2to3/fixes/fix_raise.py                                                        |    90 +
  lib3/2to3/lib2to3/fixes/fix_raw_input.py                                                    |    17 +
  lib3/2to3/lib2to3/fixes/fix_reduce.py                                                       |    35 +
  lib3/2to3/lib2to3/fixes/fix_renames.py                                                      |    70 +
  lib3/2to3/lib2to3/fixes/fix_repr.py                                                         |    23 +
  lib3/2to3/lib2to3/fixes/fix_set_literal.py                                                  |    53 +
  lib3/2to3/lib2to3/fixes/fix_standarderror.py                                                |    18 +
  lib3/2to3/lib2to3/fixes/fix_sys_exc.py                                                      |    30 +
  lib3/2to3/lib2to3/fixes/fix_throw.py                                                        |    56 +
  lib3/2to3/lib2to3/fixes/fix_tuple_params.py                                                 |   175 +
  lib3/2to3/lib2to3/fixes/fix_types.py                                                        |    62 +
  lib3/2to3/lib2to3/fixes/fix_unicode.py                                                      |    25 +
  lib3/2to3/lib2to3/fixes/fix_urllib.py                                                       |   197 +
  lib3/2to3/lib2to3/fixes/fix_ws_comma.py                                                     |    39 +
  lib3/2to3/lib2to3/fixes/fix_xrange.py                                                       |    73 +
  lib3/2to3/lib2to3/fixes/fix_xreadlines.py                                                   |    25 +
  lib3/2to3/lib2to3/fixes/fix_zip.py                                                          |    35 +
  lib3/2to3/lib2to3/main.py                                                                   |   182 +
  lib3/2to3/lib2to3/patcomp.py                                                                |   204 +
  lib3/2to3/lib2to3/pgen2/__init__.py                                                         |     4 +
  lib3/2to3/lib2to3/pgen2/conv.py                                                             |   257 +
  lib3/2to3/lib2to3/pgen2/driver.py                                                           |   147 +
  lib3/2to3/lib2to3/pgen2/grammar.py                                                          |   184 +
  lib3/2to3/lib2to3/pgen2/literals.py                                                         |    60 +
  lib3/2to3/lib2to3/pgen2/parse.py                                                            |   201 +
  lib3/2to3/lib2to3/pgen2/pgen.py                                                             |   386 +
  lib3/2to3/lib2to3/pgen2/token.py                                                            |    82 +
  lib3/2to3/lib2to3/pgen2/tokenize.py                                                         |   500 +
  lib3/2to3/lib2to3/pygram.py                                                                 |    40 +
  lib3/2to3/lib2to3/pytree.py                                                                 |   884 +
  lib3/2to3/lib2to3/refactor.py                                                               |   741 +
  lib3/2to3/lib2to3/tests/__init__.py                                                         |    24 +
  lib3/2to3/lib2to3/tests/data/README                                                         |     6 +
  lib3/2to3/lib2to3/tests/data/bom.py                                                         |     2 +
  lib3/2to3/lib2to3/tests/data/crlf.py                                                        |     3 +
  lib3/2to3/lib2to3/tests/data/different_encoding.py                                          |     6 +
  lib3/2to3/lib2to3/tests/data/fixers/bad_order.py                                            |     5 +
  lib3/2to3/lib2to3/tests/data/fixers/myfixes/__init__.py                                     |     0 
  lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_explicit.py                                 |     6 +
  lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_first.py                                    |     6 +
  lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_last.py                                     |     7 +
  lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_parrot.py                                   |    13 +
  lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_preorder.py                                 |     6 +
  lib3/2to3/lib2to3/tests/data/fixers/no_fixer_cls.py                                         |     1 +
  lib3/2to3/lib2to3/tests/data/fixers/parrot_example.py                                       |     2 +
  lib3/2to3/lib2to3/tests/data/infinite_recursion.py                                          |  2669 +++++
  lib3/2to3/lib2to3/tests/data/py2_test_grammar.py                                            |   974 ++
  lib3/2to3/lib2to3/tests/data/py3_test_grammar.py                                            |   923 ++
  lib3/2to3/lib2to3/tests/pytree_idempotency.py                                               |    92 +
  lib3/2to3/lib2to3/tests/support.py                                                          |    54 +
  lib3/2to3/lib2to3/tests/test_all_fixers.py                                                  |    23 +
  lib3/2to3/lib2to3/tests/test_fixers.py                                                      |  4515 ++++++++++
  lib3/2to3/lib2to3/tests/test_main.py                                                        |    41 +
  lib3/2to3/lib2to3/tests/test_parser.py                                                      |   217 +
  lib3/2to3/lib2to3/tests/test_pytree.py                                                      |   494 +
  lib3/2to3/lib2to3/tests/test_refactor.py                                                    |   281 +
  lib3/2to3/lib2to3/tests/test_util.py                                                        |   594 +
  lib3/2to3/scripts/benchmark.py                                                              |    58 +
  lib3/2to3/scripts/find_pattern.py                                                           |    97 +
  lib3/2to3/test.py                                                                           |    41 +
  lib3/Chameleon-2.9.2/.gitignore                                                             |    12 +
  lib3/Chameleon-2.9.2/CHANGES.rst                                                            |  1075 ++
  lib3/Chameleon-2.9.2/COPYRIGHT.txt                                                          |     7 +
  lib3/Chameleon-2.9.2/LICENSE.txt                                                            |   185 +
  lib3/Chameleon-2.9.2/Makefile                                                               |    89 +
  lib3/Chameleon-2.9.2/PKG-INFO                                                               |  1122 ++
  lib3/Chameleon-2.9.2/README.rst                                                             |    25 +
  lib3/Chameleon-2.9.2/benchmarks/bm_chameleon.py                                             |   128 +
  lib3/Chameleon-2.9.2/benchmarks/bm_mako.py                                                  |   153 +
  lib3/Chameleon-2.9.2/benchmarks/util.py                                                     |    51 +
  lib3/Chameleon-2.9.2/distribute_setup.py                                                    |   485 +
  lib3/Chameleon-2.9.2/docs/conf.py                                                           |   194 +
  lib3/Chameleon-2.9.2/docs/configuration.rst                                                 |    43 +
  lib3/Chameleon-2.9.2/docs/index.rst                                                         |   217 +
  lib3/Chameleon-2.9.2/docs/integration.rst                                                   |    41 +
  lib3/Chameleon-2.9.2/docs/library.rst                                                       |   238 +
  lib3/Chameleon-2.9.2/docs/reference.rst                                                     |  1695 +++
  lib3/Chameleon-2.9.2/setup.cfg                                                              |    14 +
  lib3/Chameleon-2.9.2/setup.py                                                               |    90 +
  lib3/Chameleon-2.9.2/src/Chameleon.egg-info/PKG-INFO                                        |  1122 ++
  lib3/Chameleon-2.9.2/src/Chameleon.egg-info/SOURCES.txt                                     |   380 +
  lib3/Chameleon-2.9.2/src/Chameleon.egg-info/dependency_links.txt                            |     1 +
  lib3/Chameleon-2.9.2/src/Chameleon.egg-info/not-zip-safe                                    |     1 +
  lib3/Chameleon-2.9.2/src/Chameleon.egg-info/top_level.txt                                   |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/__init__.py                                              |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/ast24.py                                                 |   135 +
  lib3/Chameleon-2.9.2/src/chameleon/astutil.py                                               |   926 ++
  lib3/Chameleon-2.9.2/src/chameleon/benchmark.py                                             |   478 +
  lib3/Chameleon-2.9.2/src/chameleon/codegen.py                                               |   221 +
  lib3/Chameleon-2.9.2/src/chameleon/compiler.py                                              |  1553 +++
  lib3/Chameleon-2.9.2/src/chameleon/config.py                                                |    47 +
  lib3/Chameleon-2.9.2/src/chameleon/exc.py                                                   |   289 +
  lib3/Chameleon-2.9.2/src/chameleon/i18n.py                                                  |   120 +
  lib3/Chameleon-2.9.2/src/chameleon/interfaces.py                                            |   102 +
  lib3/Chameleon-2.9.2/src/chameleon/loader.py                                                |   174 +
  lib3/Chameleon-2.9.2/src/chameleon/metal.py                                                 |    23 +
  lib3/Chameleon-2.9.2/src/chameleon/namespaces.py                                            |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/nodes.py                                                 |   210 +
  lib3/Chameleon-2.9.2/src/chameleon/parser.py                                                |   238 +
  lib3/Chameleon-2.9.2/src/chameleon/program.py                                               |    38 +
  lib3/Chameleon-2.9.2/src/chameleon/py25.py                                                  |    36 +
  lib3/Chameleon-2.9.2/src/chameleon/py26.py                                                  |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tal.py                                                   |   479 +
  lib3/Chameleon-2.9.2/src/chameleon/tales.py                                                 |   541 +
  lib3/Chameleon-2.9.2/src/chameleon/template.py                                              |   332 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/__init__.py                                        |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-interpolation.txt                       |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-variable-scope.html                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-variable-scope.pt                       |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/002-repeat-scope.pt                         |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/002.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/003-content.pt                              |    17 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/003.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/004-attributes.pt                           |    18 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/004.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/005-default.pt                              |    12 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/005.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/006-attribute-interpolation.pt              |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/006.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/007-content-interpolation.pt                |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/007.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/008-builtins.pt                             |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/008.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/009-literals.pt                             |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/009.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/010-structure.pt                            |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/010.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/011-messages.pt                             |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/011.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/012-translation.pt                          |    21 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/012.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/013-repeat-nested.pt                        |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/013.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/014-repeat-nested-similar.pt                |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/014.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/015-translation-nested.pt                   |    10 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/015.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/016-explicit-translation.pt                 |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/016.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/017-omit-tag.pt                             |    12 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/017.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/018-translation-nested-dynamic.pt           |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/018.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/019-replace.pt                              |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/019.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/020-on-error.pt                             |    10 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/020.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/021-translation-domain.pt                   |    16 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/021.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/022-switch.pt                               |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/022.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/023-condition.pt                            |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/023.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/024-namespace-elements.pt                   |    16 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/024.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/025-repeat-whitespace.pt                    |    14 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/025.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/026-repeat-variable.pt                      |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/026.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/027-attribute-replacement.pt                |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/027.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/028-attribute-toggle.pt                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/028.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/029-attribute-ordering.pt                   |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/029.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/030-repeat-tuples.pt                        |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/030.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/031-namespace-with-tal.pt                   |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/031.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/032-master-template.pt                      |    20 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/032.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/033-use-macro-trivial.pt                    |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/033.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/034-use-template-as-macro.pt                |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/034.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/035-use-macro-with-fill-slot.pt             |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/035.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/036-use-macro-inherits-dynamic-scope.pt     |     2 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/036.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/037-use-macro-local-variable-scope.pt       |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/037.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/038-use-macro-globals.pt                    |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/038.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/039-globals.pt                              |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/039.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/040-macro-using-template-symbol.pt          |    20 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/040.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/041-translate-nested-names.pt               |    22 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/041.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/042-use-macro-fill-footer.pt                |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/042.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/043-macro-nested-dynamic-vars.pt            |    19 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/043.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/044-tuple-define.pt                         |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/044.xml                                     |    10 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/045-namespaces.pt                           |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/045.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/046-extend-macro.pt                         |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/046.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/047-use-extended-macro.pt                   |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/047.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/048-use-extended-macro-fill-original.pt     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/048.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/049-entities-in-attributes.pt               |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/049.xml                                     |   Bin 
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/050-define-macro-and-use-not-extend.pt      |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/050.xml                                     |   Bin 
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/051-use-non-extended-macro.pt               |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/051.xml                                     |   Bin 
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/052-i18n-domain-inside-filled-slot.pt       |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/052.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/053-special-characters-in-attributes.pt     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/053.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/054-import-expression.pt                    |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/054.xml                                     |    10 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/055-attribute-fallback-to-dict-lookup.pt    |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/055.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/056-comment-attribute.pt                    |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/056.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/057-order.pt                                |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/057.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/058-script.pt                               |    16 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/058.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/059-embedded-javascript.pt                  |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/059.xml                                     |    10 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/060-macro-with-multiple-same-slots.pt       |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/060.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/061-fill-one-slot-but-two-defined.pt        |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/061.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/062-comments-and-expressions.pt             |    27 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/062.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/063-continuation.pt                         |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/063.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/064-tags-and-special-characters.pt          |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/064.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/065-use-macro-in-fill.pt                    |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/065.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/066-load-expression.pt                      |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/066.xml                                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/067-attribute-decode.pt                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/067.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/068-less-than-greater-than-in-attributes.pt |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/068.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/069-translation-domain-and-macro.pt         |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/069.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/070-translation-domain-and-use-macro.pt     |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/070.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/071-html-attribute-defaults.pt              |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/071.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/072-repeat-interpolation.pt                 |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/072.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/073-utf8-encoded.pt                         |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/073.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/074-encoded-template.pt                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/074.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/075-nested-macros.pt                        |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/075.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/076-nested-macro-override.pt                |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/076.xml                                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/077-i18n-attributes.pt                      |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/077.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/078-tags-and-newlines.pt                    |    23 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/078.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/079-implicit-i18n.pt                        |    16 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/079.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/080-xmlns-namespace-on-tal.pt               |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/080.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/081-load-spec.pt                            |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/081.xml                                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/082-load-spec-computed.pt                   |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/082.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/083-template-dict-to-macro.pt               |     2 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/083.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/084-interpolation-in-cdata.pt               |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/084.xml                                     |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/085-nested-translation.pt                   |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/085.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/086-self-closing.pt                         |    10 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/086.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/087-code-blocks.pt                          |    28 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/087.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/088-python-newlines.pt                      |     2 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/088.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/089.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/090.xml                                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/091.xml                                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/092.xml                                     |    10 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/093.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/094.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/095.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/096.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/097.xml                                     |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/098.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/099.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/100.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/101-unclosed-tags.html                      |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/101.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/102-unquoted-attributes.html                |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/102.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/103-simple-attribute.html                   |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/103.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/104.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/105.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/106.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/107.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/108.xml                                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/109.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/110.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/111.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/112.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/113.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/114.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/115.xml                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/116.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/117.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/118.xml                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/119.xml                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/greeting.pt                                 |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/hello_world.pt                              |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/hello_world.txt                             |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.html                                   |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.pt                                     |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.txt                                    |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/002.pt                                     |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/003.pt                                     |    17 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/004.pt                                     |    18 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/005.pt                                     |    12 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/006.pt                                     |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/007.pt                                     |    14 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/008.pt                                     |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/009.pt                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/010.pt                                     |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/011-en.pt                                  |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/011.pt                                     |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/012-en.pt                                  |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/012.pt                                     |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/013.pt                                     |    22 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/014.pt                                     |    12 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/015-en.pt                                  |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/015.pt                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/016-en.pt                                  |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/016.pt                                     |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/017.pt                                     |    12 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/018-en.pt                                  |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/018.pt                                     |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/019.pt                                     |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/020.pt                                     |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/021-en.pt                                  |    12 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/021.pt                                     |    12 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/022.pt                                     |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/023.pt                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/024.pt                                     |    14 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/025.pt                                     |    23 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/026.pt                                     |    17 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/027.pt                                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/028.pt                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/029.pt                                     |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/030.pt                                     |    10 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/031.pt                                     |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/032.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/033.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/034.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/035.pt                                     |    17 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/036.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/037.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/038.pt                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/039.pt                                     |     0 
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/040.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/041.pt                                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/042.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/043.pt                                     |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/044.pt                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/045.pt                                     |    12 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/046.pt                                     |    17 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/047.pt                                     |    17 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/048.pt                                     |    17 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/049.pt                                     |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/050.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/051.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/052.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/053.pt                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/054.pt                                     |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/055.pt                                     |     4 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/056.pt                                     |     7 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/057.pt                                     |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/058.pt                                     |    16 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/059.pt                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/060.pt                                     |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/061.pt                                     |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/062.pt                                     |    27 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/063.pt                                     |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/064.pt                                     |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/065.pt                                     |    13 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/066.pt                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/067.pt                                     |     6 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/068.pt                                     |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/069-en.pt                                  |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/069.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/070-en.pt                                  |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/070.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/071.pt                                     |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/072.pt                                     |    19 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/073.pt                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/074.pt                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/075.pt                                     |    19 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/076.pt                                     |    17 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/077-en.pt                                  |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/077.pt                                     |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/078.pt                                     |    11 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/079-en.pt                                  |    16 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/079.pt                                     |    16 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/080.pt                                     |     3 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/081.pt                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/082.pt                                     |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/083.pt                                     |    15 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/084.pt                                     |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/085-en.pt                                  |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/085.pt                                     |     9 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/086.pt                                     |    18 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/087.pt                                     |    25 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/088.pt                                     |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/101.html                                   |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/102.html                                   |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/103.html                                   |     8 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/greeting.pt                                |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/hello_world.pt                             |     5 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/hello_world.txt                            |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/test_doctests.py                                   |    40 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/test_loader.py                                     |    79 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/test_parser.py                                     |    92 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/test_sniffing.py                                   |   124 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/test_templates.py                                  |   679 +
  lib3/Chameleon-2.9.2/src/chameleon/tests/test_tokenizer.py                                  |    47 +
  lib3/Chameleon-2.9.2/src/chameleon/tokenize.py                                              |   144 +
  lib3/Chameleon-2.9.2/src/chameleon/utils.py                                                 |   429 +
  lib3/Chameleon-2.9.2/src/chameleon/zpt/__init__.py                                          |     1 +
  lib3/Chameleon-2.9.2/src/chameleon/zpt/loader.py                                            |    30 +
  lib3/Chameleon-2.9.2/src/chameleon/zpt/program.py                                           |   751 +
  lib3/Chameleon-2.9.2/src/chameleon/zpt/template.py                                          |   409 +
  lib3/Chameleon-2.9.2/src/ordereddict.py                                                     |   127 +
  lib3/Chameleon-2.9.2/src/pkg_resources.py                                                   |  2838 ++++++
  lib3/Chameleon-2.9.2/tox.ini                                                                |    53 +
  lib3/Mako-0.7.3/CHANGES                                                                     |   847 +
  lib3/Mako-0.7.3/LICENSE                                                                     |    20 +
  lib3/Mako-0.7.3/MANIFEST.in                                                                 |    11 +
  lib3/Mako-0.7.3/Mako.egg-info/PKG-INFO                                                      |    71 +
  lib3/Mako-0.7.3/Mako.egg-info/SOURCES.txt                                                   |   171 +
  lib3/Mako-0.7.3/Mako.egg-info/dependency_links.txt                                          |     1 +
  lib3/Mako-0.7.3/Mako.egg-info/entry_points.txt                                              |    14 +
  lib3/Mako-0.7.3/Mako.egg-info/not-zip-safe                                                  |     1 +
  lib3/Mako-0.7.3/Mako.egg-info/requires.txt                                                  |     4 +
  lib3/Mako-0.7.3/Mako.egg-info/top_level.txt                                                 |     1 +
  lib3/Mako-0.7.3/PKG-INFO                                                                    |    71 +
  lib3/Mako-0.7.3/README.rst                                                                  |    52 +
  lib3/Mako-0.7.3/distribute_setup.py                                                         |   485 +
  lib3/Mako-0.7.3/doc/_sources/caching.txt                                                    |   393 +
  lib3/Mako-0.7.3/doc/_sources/defs.txt                                                       |   622 +
  lib3/Mako-0.7.3/doc/_sources/filtering.txt                                                  |   344 +
  lib3/Mako-0.7.3/doc/_sources/index.txt                                                      |    22 +
  lib3/Mako-0.7.3/doc/_sources/inheritance.txt                                                |   534 +
  lib3/Mako-0.7.3/doc/_sources/namespaces.txt                                                 |   349 +
  lib3/Mako-0.7.3/doc/_sources/runtime.txt                                                    |   448 +
  lib3/Mako-0.7.3/doc/_sources/syntax.txt                                                     |   469 +
  lib3/Mako-0.7.3/doc/_sources/unicode.txt                                                    |   345 +
  lib3/Mako-0.7.3/doc/_sources/usage.txt                                                      |   520 +
  lib3/Mako-0.7.3/doc/_static/basic.css                                                       |   540 +
  lib3/Mako-0.7.3/doc/_static/comment-bright.png                                              |   Bin 
  lib3/Mako-0.7.3/doc/_static/comment-close.png                                               |   Bin 
  lib3/Mako-0.7.3/doc/_static/comment.png                                                     |   Bin 
  lib3/Mako-0.7.3/doc/_static/default.css                                                     |   256 +
  lib3/Mako-0.7.3/doc/_static/docs.css                                                        |   438 +
  lib3/Mako-0.7.3/doc/_static/doctools.js                                                     |   247 +
  lib3/Mako-0.7.3/doc/_static/down-pressed.png                                                |   Bin 
  lib3/Mako-0.7.3/doc/_static/down.png                                                        |   Bin 
  lib3/Mako-0.7.3/doc/_static/file.png                                                        |   Bin 
  lib3/Mako-0.7.3/doc/_static/jquery.js                                                       |   154 +
  lib3/Mako-0.7.3/doc/_static/makoLogo.png                                                    |   Bin 
  lib3/Mako-0.7.3/doc/_static/minus.png                                                       |   Bin 
  lib3/Mako-0.7.3/doc/_static/plus.png                                                        |   Bin 
  lib3/Mako-0.7.3/doc/_static/pygments.css                                                    |    62 +
  lib3/Mako-0.7.3/doc/_static/searchtools.js                                                  |   560 +
  lib3/Mako-0.7.3/doc/_static/sidebar.js                                                      |   151 +
  lib3/Mako-0.7.3/doc/_static/site.css                                                        |    86 +
  lib3/Mako-0.7.3/doc/_static/underscore.js                                                   |    23 +
  lib3/Mako-0.7.3/doc/_static/up-pressed.png                                                  |   Bin 
  lib3/Mako-0.7.3/doc/_static/up.png                                                          |   Bin 
  lib3/Mako-0.7.3/doc/_static/websupport.js                                                   |   808 +
  lib3/Mako-0.7.3/doc/build/Makefile                                                          |   137 +
  lib3/Mako-0.7.3/doc/build/builder/__init__.py                                               |     0 
  lib3/Mako-0.7.3/doc/build/builder/builders.py                                               |    97 +
  lib3/Mako-0.7.3/doc/build/builder/util.py                                                   |    12 +
  lib3/Mako-0.7.3/doc/build/caching.rst                                                       |   393 +
  lib3/Mako-0.7.3/doc/build/conf.py                                                           |   287 +
  lib3/Mako-0.7.3/doc/build/defs.rst                                                          |   622 +
  lib3/Mako-0.7.3/doc/build/filtering.rst                                                     |   344 +
  lib3/Mako-0.7.3/doc/build/index.rst                                                         |    22 +
  lib3/Mako-0.7.3/doc/build/inheritance.rst                                                   |   534 +
  lib3/Mako-0.7.3/doc/build/namespaces.rst                                                    |   349 +
  lib3/Mako-0.7.3/doc/build/runtime.rst                                                       |   448 +
  lib3/Mako-0.7.3/doc/build/static/docs.css                                                   |   438 +
  lib3/Mako-0.7.3/doc/build/static/makoLogo.png                                               |   Bin 
  lib3/Mako-0.7.3/doc/build/static/site.css                                                   |    86 +
  lib3/Mako-0.7.3/doc/build/syntax.rst                                                        |   469 +
  lib3/Mako-0.7.3/doc/build/templates/base.mako                                               |    60 +
  lib3/Mako-0.7.3/doc/build/templates/genindex.mako                                           |    77 +
  lib3/Mako-0.7.3/doc/build/templates/layout.mako                                             |   199 +
  lib3/Mako-0.7.3/doc/build/templates/page.mako                                               |     2 +
  lib3/Mako-0.7.3/doc/build/templates/rtd_layout.mako                                         |   174 +
  lib3/Mako-0.7.3/doc/build/templates/search.mako                                             |    25 +
  lib3/Mako-0.7.3/doc/build/unicode.rst                                                       |   345 +
  lib3/Mako-0.7.3/doc/build/usage.rst                                                         |   520 +
  lib3/Mako-0.7.3/doc/caching.html                                                            |   779 +
  lib3/Mako-0.7.3/doc/defs.html                                                               |   728 +
  lib3/Mako-0.7.3/doc/filtering.html                                                          |   478 +
  lib3/Mako-0.7.3/doc/genindex.html                                                           |   916 ++
  lib3/Mako-0.7.3/doc/index.html                                                              |   230 +
  lib3/Mako-0.7.3/doc/inheritance.html                                                        |   673 +
  lib3/Mako-0.7.3/doc/namespaces.html                                                         |   649 +
  lib3/Mako-0.7.3/doc/runtime.html                                                            |   710 +
  lib3/Mako-0.7.3/doc/search.html                                                             |   162 +
  lib3/Mako-0.7.3/doc/searchindex.js                                                          |     1 +
  lib3/Mako-0.7.3/doc/syntax.html                                                             |   596 +
  lib3/Mako-0.7.3/doc/unicode.html                                                            |   476 +
  lib3/Mako-0.7.3/doc/usage.html                                                              |  1057 ++
  lib3/Mako-0.7.3/examples/bench/basic.py                                                     |   191 +
  lib3/Mako-0.7.3/examples/bench/cheetah/footer.tmpl                                          |     2 +
  lib3/Mako-0.7.3/examples/bench/cheetah/header.tmpl                                          |     5 +
  lib3/Mako-0.7.3/examples/bench/cheetah/template.tmpl                                        |    31 +
  lib3/Mako-0.7.3/examples/bench/django/templatetags/__init__.py                              |     0 
  lib3/Mako-0.7.3/examples/bench/django/templatetags/bench.py                                 |     8 +
  lib3/Mako-0.7.3/examples/bench/kid/base.kid                                                 |    15 +
  lib3/Mako-0.7.3/examples/bench/kid/template.kid                                             |    22 +
  lib3/Mako-0.7.3/examples/bench/myghty/base.myt                                              |    29 +
  lib3/Mako-0.7.3/examples/bench/myghty/template.myt                                          |    30 +
  lib3/Mako-0.7.3/examples/wsgi/run_wsgi.py                                                   |    78 +
  lib3/Mako-0.7.3/mako/__init__.py                                                            |     9 +
  lib3/Mako-0.7.3/mako/_ast_util.py                                                           |   839 +
  lib3/Mako-0.7.3/mako/ast.py                                                                 |   151 +
  lib3/Mako-0.7.3/mako/cache.py                                                               |   236 +
  lib3/Mako-0.7.3/mako/codegen.py                                                             |  1215 ++
  lib3/Mako-0.7.3/mako/exceptions.py                                                          |   362 +
  lib3/Mako-0.7.3/mako/ext/__init__.py                                                        |     0 
  lib3/Mako-0.7.3/mako/ext/autohandler.py                                                     |    65 +
  lib3/Mako-0.7.3/mako/ext/babelplugin.py                                                     |   132 +
  lib3/Mako-0.7.3/mako/ext/beaker_cache.py                                                    |    70 +
  lib3/Mako-0.7.3/mako/ext/preprocessors.py                                                   |    20 +
  lib3/Mako-0.7.3/mako/ext/pygmentplugin.py                                                   |   122 +
  lib3/Mako-0.7.3/mako/ext/turbogears.py                                                      |    57 +
  lib3/Mako-0.7.3/mako/filters.py                                                             |   191 +
  lib3/Mako-0.7.3/mako/lexer.py                                                               |   442 +
  lib3/Mako-0.7.3/mako/lookup.py                                                              |   354 +
  lib3/Mako-0.7.3/mako/parsetree.py                                                           |   594 +
  lib3/Mako-0.7.3/mako/pygen.py                                                               |   283 +
  lib3/Mako-0.7.3/mako/pyparser.py                                                            |   551 +
  lib3/Mako-0.7.3/mako/runtime.py                                                             |   842 +
  lib3/Mako-0.7.3/mako/template.py                                                            |   650 +
  lib3/Mako-0.7.3/mako/util.py                                                                |   437 +
  lib3/Mako-0.7.3/scripts/mako-render                                                         |    46 +
  lib3/Mako-0.7.3/setup.cfg                                                                   |     5 +
  lib3/Mako-0.7.3/setup.py                                                                    |    62 +
  lib3/Mako-0.7.3/test/__init__.py                                                            |   145 +
  lib3/Mako-0.7.3/test/foo/__init__.py                                                        |     0 
  lib3/Mako-0.7.3/test/foo/test_ns.py                                                         |     7 +
  lib3/Mako-0.7.3/test/sample_module_namespace.py                                             |     7 +
  lib3/Mako-0.7.3/test/templates/badbom.html                                                  |     2 +
  lib3/Mako-0.7.3/test/templates/bom.html                                                     |     1 +
  lib3/Mako-0.7.3/test/templates/bommagic.html                                                |     2 +
  lib3/Mako-0.7.3/test/templates/chs_unicode.html                                             |    11 +
  lib3/Mako-0.7.3/test/templates/chs_unicode_py3k.html                                        |    11 +
  lib3/Mako-0.7.3/test/templates/chs_utf8.html                                                |    17 +
  lib3/Mako-0.7.3/test/templates/crlf.html                                                    |    19 +
  lib3/Mako-0.7.3/test/templates/foo/modtest.html.py                                          |    25 +
  lib3/Mako-0.7.3/test/templates/gettext.mako                                                 |    89 +
  lib3/Mako-0.7.3/test/templates/index.html                                                   |     1 +
  lib3/Mako-0.7.3/test/templates/internationalization.html                                    |   920 ++
  lib3/Mako-0.7.3/test/templates/modtest.html                                                 |     1 +
  lib3/Mako-0.7.3/test/templates/othersubdir/foo.html                                         |     0 
  lib3/Mako-0.7.3/test/templates/read_unicode.html                                            |    10 +
  lib3/Mako-0.7.3/test/templates/read_unicode_py3k.html                                       |    10 +
  lib3/Mako-0.7.3/test/templates/runtimeerr.html                                              |     4 +
  lib3/Mako-0.7.3/test/templates/runtimeerr_py3k.html                                         |     4 +
  lib3/Mako-0.7.3/test/templates/subdir/foo/modtest.html.py                                   |    25 +
  lib3/Mako-0.7.3/test/templates/subdir/incl.html                                             |     2 +
  lib3/Mako-0.7.3/test/templates/subdir/index.html                                            |     3 +
  lib3/Mako-0.7.3/test/templates/subdir/modtest.html                                          |     1 +
  lib3/Mako-0.7.3/test/templates/unicode.html                                                 |     2 +
  lib3/Mako-0.7.3/test/templates/unicode_arguments.html                                       |    10 +
  lib3/Mako-0.7.3/test/templates/unicode_arguments_py3k.html                                  |    10 +
  lib3/Mako-0.7.3/test/templates/unicode_code.html                                            |     7 +
  lib3/Mako-0.7.3/test/templates/unicode_code_py3k.html                                       |     7 +
  lib3/Mako-0.7.3/test/templates/unicode_expr.html                                            |     2 +
  lib3/Mako-0.7.3/test/templates/unicode_expr_py3k.html                                       |     2 +
  lib3/Mako-0.7.3/test/templates/unicode_runtime_error.html                                   |     2 +
  lib3/Mako-0.7.3/test/templates/unicode_syntax_error.html                                    |     2 +
  lib3/Mako-0.7.3/test/test_ast.py                                                            |   334 +
  lib3/Mako-0.7.3/test/test_babelplugin.py                                                    |    44 +
  lib3/Mako-0.7.3/test/test_block.py                                                          |   569 +
  lib3/Mako-0.7.3/test/test_cache.py                                                          |   557 +
  lib3/Mako-0.7.3/test/test_call.py                                                           |   515 +
  lib3/Mako-0.7.3/test/test_decorators.py                                                     |   110 +
  lib3/Mako-0.7.3/test/test_def.py                                                            |   678 +
  lib3/Mako-0.7.3/test/test_exceptions.py                                                     |   299 +
  lib3/Mako-0.7.3/test/test_filters.py                                                        |   335 +
  lib3/Mako-0.7.3/test/test_inheritance.py                                                    |   350 +
  lib3/Mako-0.7.3/test/test_lexer.py                                                          |   871 +
  lib3/Mako-0.7.3/test/test_lookup.py                                                         |   104 +
  lib3/Mako-0.7.3/test/test_loop.py                                                           |   295 +
  lib3/Mako-0.7.3/test/test_lru.py                                                            |   111 +
  lib3/Mako-0.7.3/test/test_namespace.py                                                      |   792 +
  lib3/Mako-0.7.3/test/test_pygen.py                                                          |   252 +
  lib3/Mako-0.7.3/test/test_template.py                                                       |  1242 ++
  lib3/Mako-0.7.3/test/test_tgplugin.py                                                       |    42 +
  lib3/Mako-0.7.3/test/test_util.py                                                           |    50 +
  lib3/Mako-0.7.3/test/util.py                                                                |     7 +
  lib3/mako-0.3.6/.hgignore                                                                   |     7 +
  lib3/mako-0.3.6/CHANGES                                                                     |   590 +
  lib3/mako-0.3.6/LICENSE                                                                     |    20 +
  lib3/mako-0.3.6/MANIFEST.in                                                                 |    12 +
  lib3/mako-0.3.6/README                                                                      |    25 +
  lib3/mako-0.3.6/README.py3k                                                                 |    56 +
  lib3/mako-0.3.6/distribute_setup.py                                                         |   485 +
  lib3/mako-0.3.6/doc/build/Makefile                                                          |   143 +
  lib3/mako-0.3.6/doc/build/builder/builders.py                                               |    69 +
  lib3/mako-0.3.6/doc/build/builder/util.py                                                   |    12 +
  lib3/mako-0.3.6/doc/build/caching.rst                                                       |   127 +
  lib3/mako-0.3.6/doc/build/conf.py                                                           |   280 +
  lib3/mako-0.3.6/doc/build/defs.rst                                                          |   436 +
  lib3/mako-0.3.6/doc/build/filtering.rst                                                     |   340 +
  lib3/mako-0.3.6/doc/build/index.rst                                                         |    21 +
  lib3/mako-0.3.6/doc/build/inheritance.rst                                                   |   321 +
  lib3/mako-0.3.6/doc/build/namespaces.rst                                                    |   341 +
  lib3/mako-0.3.6/doc/build/runtime.rst                                                       |   238 +
  lib3/mako-0.3.6/doc/build/static/docs.css                                                   |   288 +
  lib3/mako-0.3.6/doc/build/syntax.rst                                                        |   417 +
  lib3/mako-0.3.6/doc/build/templates/genindex.mako                                           |    72 +
  lib3/mako-0.3.6/doc/build/templates/layout.mako                                             |   130 +
  lib3/mako-0.3.6/doc/build/templates/page.mako                                               |     2 +
  lib3/mako-0.3.6/doc/build/templates/search.mako                                             |    22 +
  lib3/mako-0.3.6/doc/build/templates/site_base.mako                                          |    30 +
  lib3/mako-0.3.6/doc/build/templates/static_base.mako                                        |    19 +
  lib3/mako-0.3.6/doc/build/unicode.rst                                                       |   337 +
  lib3/mako-0.3.6/doc/build/usage.rst                                                         |   484 +
  lib3/mako-0.3.6/examples/bench/basic.py                                                     |   161 +
  lib3/mako-0.3.6/examples/bench/basic.py.orig                                                |   161 +
  lib3/mako-0.3.6/examples/bench/cheetah/footer.tmpl                                          |     2 +
  lib3/mako-0.3.6/examples/bench/cheetah/header.tmpl                                          |     5 +
  lib3/mako-0.3.6/examples/bench/cheetah/template.tmpl                                        |    31 +
  lib3/mako-0.3.6/examples/bench/django/templates/base.html                                   |    14 +
  lib3/mako-0.3.6/examples/bench/django/templates/template.html                               |    22 +
  lib3/mako-0.3.6/examples/bench/django/templatetags/bench.py                                 |     8 +
  lib3/mako-0.3.6/examples/bench/genshi/base.html                                             |    17 +
  lib3/mako-0.3.6/examples/bench/genshi/template.html                                         |    24 +
  lib3/mako-0.3.6/examples/bench/kid/base.kid                                                 |    15 +
  lib3/mako-0.3.6/examples/bench/kid/template.kid                                             |    22 +
  lib3/mako-0.3.6/examples/bench/mako/footer.html                                             |     2 +
  lib3/mako-0.3.6/examples/bench/mako/header.html                                             |     5 +
  lib3/mako-0.3.6/examples/bench/mako/template.html                                           |    31 +
  lib3/mako-0.3.6/examples/bench/mako_inheritance/base.html                                   |    24 +
  lib3/mako-0.3.6/examples/bench/mako_inheritance/template.html                               |    15 +
  lib3/mako-0.3.6/examples/bench/myghty/base.myt                                              |    29 +
  lib3/mako-0.3.6/examples/bench/myghty/template.myt                                          |    30 +
  lib3/mako-0.3.6/examples/wsgi/htdocs/index.html                                             |     8 +
  lib3/mako-0.3.6/examples/wsgi/run_wsgi.py                                                   |    78 +
  lib3/mako-0.3.6/examples/wsgi/templates/root.html                                           |     7 +
  lib3/mako-0.3.6/mako/__init__.py                                                            |     9 +
  lib3/mako-0.3.6/mako/_ast_util.py                                                           |   834 +
  lib3/mako-0.3.6/mako/ast.py                                                                 |   143 +
  lib3/mako-0.3.6/mako/cache.py                                                               |   118 +
  lib3/mako-0.3.6/mako/codegen.py                                                             |   958 ++
  lib3/mako-0.3.6/mako/exceptions.py                                                          |   309 +
  lib3/mako-0.3.6/mako/ext/autohandler.py                                                     |    59 +
  lib3/mako-0.3.6/mako/ext/babelplugin.py                                                     |   123 +
  lib3/mako-0.3.6/mako/ext/preprocessors.py                                                   |    14 +
  lib3/mako-0.3.6/mako/ext/pygmentplugin.py                                                   |   101 +
  lib3/mako-0.3.6/mako/ext/turbogears.py                                                      |    50 +
  lib3/mako-0.3.6/mako/filters.py                                                             |   189 +
  lib3/mako-0.3.6/mako/lexer.py                                                               |   415 +
  lib3/mako-0.3.6/mako/lookup.py                                                              |   321 +
  lib3/mako-0.3.6/mako/parsetree.py                                                           |   497 +
  lib3/mako-0.3.6/mako/pygen.py                                                               |   285 +
  lib3/mako-0.3.6/mako/pyparser.py                                                            |   533 +
  lib3/mako-0.3.6/mako/runtime.py                                                             |   651 +
  lib3/mako-0.3.6/mako/template.py                                                            |   510 +
  lib3/mako-0.3.6/mako/util.py                                                                |   315 +
  lib3/mako-0.3.6/scripts/mako-render                                                         |    38 +
  lib3/mako-0.3.6/setup.cfg                                                                   |     2 +
  lib3/mako-0.3.6/setup.py                                                                    |    68 +
  lib3/mako-0.3.6/test/__init__.py                                                            |    93 +
  lib3/mako-0.3.6/test/foo/test_ns.py                                                         |     7 +
  lib3/mako-0.3.6/test/sample_module_namespace.py                                             |     7 +
  lib3/mako-0.3.6/test/templates/badbom.html                                                  |     2 +
  lib3/mako-0.3.6/test/templates/bom.html                                                     |     1 +
  lib3/mako-0.3.6/test/templates/bommagic.html                                                |     2 +
  lib3/mako-0.3.6/test/templates/chs_unicode.html                                             |    11 +
  lib3/mako-0.3.6/test/templates/chs_unicode_py3k.html                                        |    11 +
  lib3/mako-0.3.6/test/templates/chs_utf8.html                                                |    17 +
  lib3/mako-0.3.6/test/templates/crlf.html                                                    |    19 +
  lib3/mako-0.3.6/test/templates/foo/modtest.html.py                                          |    25 +
  lib3/mako-0.3.6/test/templates/gettext.mako                                                 |    83 +
  lib3/mako-0.3.6/test/templates/index.html                                                   |     1 +
  lib3/mako-0.3.6/test/templates/internationalization.html                                    |   920 ++
  lib3/mako-0.3.6/test/templates/modtest.html                                                 |     1 +
  lib3/mako-0.3.6/test/templates/read_unicode.html                                            |    10 +
  lib3/mako-0.3.6/test/templates/read_unicode_py3k.html                                       |    10 +
  lib3/mako-0.3.6/test/templates/runtimeerr.html                                              |     4 +
  lib3/mako-0.3.6/test/templates/runtimeerr_py3k.html                                         |     4 +
  lib3/mako-0.3.6/test/templates/subdir/foo/modtest.html.py                                   |    25 +
  lib3/mako-0.3.6/test/templates/subdir/incl.html                                             |     2 +
  lib3/mako-0.3.6/test/templates/subdir/index.html                                            |     3 +
  lib3/mako-0.3.6/test/templates/subdir/modtest.html                                          |     1 +
  lib3/mako-0.3.6/test/templates/unicode.html                                                 |     2 +
  lib3/mako-0.3.6/test/templates/unicode_arguments.html                                       |    10 +
  lib3/mako-0.3.6/test/templates/unicode_arguments_py3k.html                                  |    10 +
  lib3/mako-0.3.6/test/templates/unicode_code.html                                            |     7 +
  lib3/mako-0.3.6/test/templates/unicode_code_py3k.html                                       |     7 +
  lib3/mako-0.3.6/test/templates/unicode_expr.html                                            |     2 +
  lib3/mako-0.3.6/test/templates/unicode_expr_py3k.html                                       |     2 +
  lib3/mako-0.3.6/test/templates/unicode_runtime_error.html                                   |     2 +
  lib3/mako-0.3.6/test/templates/unicode_syntax_error.html                                    |     2 +
  lib3/mako-0.3.6/test/test_ast.py                                                            |   273 +
  lib3/mako-0.3.6/test/test_babelplugin.py                                                    |    42 +
  lib3/mako-0.3.6/test/test_cache.py                                                          |   404 +
  lib3/mako-0.3.6/test/test_call.py                                                           |   447 +
  lib3/mako-0.3.6/test/test_decorators.py                                                     |   110 +
  lib3/mako-0.3.6/test/test_def.py                                                            |   550 +
  lib3/mako-0.3.6/test/test_exceptions.py                                                     |   188 +
  lib3/mako-0.3.6/test/test_filters.py                                                        |   290 +
  lib3/mako-0.3.6/test/test_inheritance.py                                                    |   350 +
  lib3/mako-0.3.6/test/test_lexer.py                                                          |   854 +
  lib3/mako-0.3.6/test/test_lookup.py                                                         |    65 +
  lib3/mako-0.3.6/test/test_lru.py                                                            |   111 +
  lib3/mako-0.3.6/test/test_namespace.py                                                      |   792 +
  lib3/mako-0.3.6/test/test_pygen.py                                                          |   252 +
  lib3/mako-0.3.6/test/test_template.py                                                       |   936 ++
  lib3/mako-0.3.6/test/test_tgplugin.py                                                       |    42 +
  lib3/mako-0.3.6/test/util.py                                                                |     7 +
  lib3/pkg_resources.py                                                                       |  2838 ------
  make_perf3.sh                                                                               |    65 -
  perf.py                                                                                     |    14 +-
  790 files changed, 100762 insertions(+), 2908 deletions(-)


diff --git a/lib3/2to3/2to3 b/lib3/2to3/2to3
new file mode 100755
--- /dev/null
+++ b/lib3/2to3/2to3
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+import sys
+from lib2to3.main import main
+
+sys.exit(main("lib2to3.fixes"))
diff --git a/lib3/2to3/HACKING b/lib3/2to3/HACKING
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/HACKING
@@ -0,0 +1,49 @@
+Tips/tricks/hints for writing new fixers:
+
+    * Don't write your own PATTERN from scratch; that's what
+      scripts/find_pattern.py is for.
+    
+    * If your fixer works by changing a node's children list or a leaf's value,
+      be sure to call the node/leaf's changed() method. This to be sure the main
+      script will recognize that the tree has changed.
+
+
+Putting 2to3 to work somewhere else:
+
+    * By default, 2to3 uses a merger of Python 2.x and Python 3's grammars.  If
+      you want to support a different grammar, just replace the Grammar.txt file
+      with Grammar/Grammar from your chosen Python version.
+
+    * The real heart of 2to3 is the concrete syntax tree parser in pgen2; this
+      chunk of the system is suitable for a wide range of applications that
+      require CST transformation. All that's required is to rip off the fixer
+      layer and replace it with something else that walks the tree. One
+      application would be a tool to check/enforce style guidelines; this could
+      leverage 90% of the existing infrastructure with primarily cosmetic
+      changes (e.g., fixes/fix_*.py -> styles/style_*.py).
+
+
+TODO
+
+    Simple:
+    #######
+    
+    * Refactor common code out of fixes/fix_*.py into fixer_util (on-going).
+
+    * Document how to write fixers.
+
+
+    Complex:
+    ########
+
+    * Come up with a scheme to hide the details of suite indentation (some kind
+      of custom pytree node for suites, probably). This will automatically
+      reindent all code with spaces, tied into a refactor.py flag that allows
+      you to specify the indent level.
+
+    * Remove the need to explicitly assign a node's parent attribute.  This
+      could be gone with a magic children list.
+
+    * Import statements are complicated and a pain to handle, and there are many
+      fixers that manipulate them. It would be nice to have a little API for
+      manipulating imports in fixers.
diff --git a/lib3/2to3/README b/lib3/2to3/README
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/README
@@ -0,0 +1,255 @@
+Abstract
+========
+
+A refactoring tool for converting Python 2.x code to 3.x.
+
+This is a work in progress! Bugs should be reported to http://bugs.python.org/
+under the "2to3" category.
+
+
+General usage
+=============
+
+Run ``./2to3`` to convert stdin (``-``), files or directories given as
+arguments.
+
+2to3 must be run with at least Python 2.5. The intended path for migrating to
+Python 3.x is to first migrate to 2.6 (in order to take advantage of Python
+2.6's runtime compatibility checks).
+
+
+Files
+=====
+
+README                        - this file
+lib2to3/refactor.py           - main program; use this to convert files or directory trees
+test.py                       - runs all unittests for 2to3
+lib2to3/patcomp.py            - pattern compiler
+lib2to3/pytree.py             - parse tree nodes (not specific to Python, despite the name!)
+lib2to3/pygram.py             - code specific to the Python grammar
+scripts/example.py            - example input for play.py and fix_*.py
+scripts/find_pattern.py       - script to help determine the PATTERN for a new fix
+lib2to3/Grammar.txt           - Python grammar input (accepts 2.x and 3.x syntax)
+lib2to3/Grammar.pickle        - pickled grammar tables (generated file, not in subversion)
+lib2to3/PatternGrammar.txt    - grammar for the pattern language used by patcomp.py
+lib2to3/PatternGrammar.pickle - pickled pattern grammar tables (generated file)
+lib2to3/pgen2/                - Parser generator and driver ([1]_, [2]_)
+lib2to3/fixes/                - Individual transformations
+lib2to3/tests/                - Test files for pytree, fixers, grammar, etc
+
+
+Capabilities
+============
+
+A quick run-through of 2to3's current fixers:
+
+* **fix_apply** - convert apply() calls to real function calls.
+
+* **fix_callable** - converts callable(obj) into hasattr(obj, '__call__').
+
+* **fix_dict** - fix up dict.keys(), .values(), .items() and their iterator
+  versions.
+  
+* **fix_except** - adjust "except" statements to Python 3 syntax (PEP 3110).
+
+* **fix_exec** - convert "exec" statements to exec() function calls.
+
+* **fix_execfile** - execfile(filename, ...) -> exec(open(filename).read())
+
+* **fix_filter** - changes filter(F, X) into list(filter(F, X)).
+
+* **fix_funcattrs** - fix function attribute names (f.func_x -> f.__x__).
+
+* **fix_has_key** - "d.has_key(x)" -> "x in d".
+
+* **fix_idioms** - convert type(x) == T to isinstance(x, T), "while 1:" to
+  "while True:", plus others. This fixer must be explicitly requested
+  with "-f idioms".
+
+* **fix_imports** - Fix (some) incompatible imports.
+
+* **fix_imports2** - Fix (some) incompatible imports that must run after
+                     **test_imports**.
+
+* **fix_input** - "input()" -> "eval(input())" (PEP 3111).
+
+* **fix_intern** - "intern(x)" -> "sys.intern(x)".
+
+* **fix_long** - remove all usage of explicit longs in favor of ints.
+
+* **fix_map** - generally changes map(F, ...) into list(map(F, ...)).
+
+* **fix_ne** - convert the "<>" operator to "!=".
+
+* **fix_next** - fixer for it.next() -> next(it) (PEP 3114).
+
+* **fix_nonzero** - convert __nonzero__() methods to __bool__() methods.
+
+* **fix_numliterals** - tweak certain numeric literals to be 3.0-compliant.
+
+* **fix_paren** - Add parentheses to places where they are needed in list
+    comprehensions and generator expressions.
+
+* **fix_operator** - fixer for functions gone from the operator module.
+
+* **fix_print** - convert "print" statements to print() function calls.
+
+* **fix_raise** - convert "raise" statements to Python 3 syntax (PEP 3109).
+
+* **fix_raw_input** - "raw_input()" -> "input()" (PEP 3111).
+
+* **fix_repr** - swap backticks for repr() calls.
+
+* **fix_standarderror** - StandardError -> Exception.
+
+* **fix_sys_exc** - Converts * **"sys.exc_info", "sys.exc_type", and
+  "sys.exc_value" to sys.exc_info()
+
+* **fix_throw** - fix generator.throw() calls to be 3.0-compliant (PEP 3109).
+
+* **fix_tuple_params** - remove tuple parameters from function, method and
+  lambda declarations (PEP 3113).
+  
+* **fix_unicode** - convert, e.g., u"..." to "...", unicode(x) to str(x), etc.
+
+* **fix_urllib** - Fix imports for urllib and urllib2.
+  
+* **fix_xrange** - "xrange()" -> "range()".
+
+* **fix_xreadlines** - "for x in f.xreadlines():" -> "for x in f:". Also,
+  "g(f.xreadlines)" -> "g(f.__iter__)".
+
+* **fix_metaclass** - move __metaclass__ = M to class X(metaclass=M)
+
+
+Limitations
+===========
+
+General Limitations
+-------------------
+
+* In general, fixers that convert a function or method call will not detect
+  something like ::
+
+      a = apply
+      a(f, *args)
+    
+  or ::
+
+      m = d.has_key
+      if m(5):
+          ...
+        
+* Fixers that look for attribute references will not detect when getattr() or
+  setattr() is used to access those attributes.
+  
+* The contents of eval() calls and "exec" statements will not be checked by
+  2to3.
+
+        
+Caveats for Specific Fixers
+---------------------------
+
+fix_except
+''''''''''
+
+"except" statements like ::
+
+    except Exception, (a, b):
+        ...
+
+are not fixed up. The ability to treat exceptions as sequences is being
+removed in Python 3, so there is no straightforward, automatic way to
+adjust these statements.
+
+This is seen frequently when dealing with OSError.
+
+
+fix_filter
+''''''''''
+
+The transformation is not correct if the original code depended on
+filter(F, X) returning a string if X is a string (or a tuple if X is a
+tuple, etc).  That would require type inference, which we don't do.  Python
+2.6's Python 3 compatibility mode should be used to detect such cases.
+
+
+fix_has_key
+'''''''''''
+
+While the primary target of this fixer is dict.has_key(), the
+fixer will change any has_key() method call, regardless of what class it
+belongs to. Anyone using non-dictionary classes with has_key() methods is
+advised to pay close attention when using this fixer.
+
+
+fix_map
+'''''''
+
+The transformation is not correct if the original code was depending on
+map(F, X, Y, ...) to go on until the longest argument is exhausted,
+substituting None for missing values -- like zip(), it now stops as
+soon as the shortest argument is exhausted.
+
+
+fix_raise
+'''''''''
+
+"raise E, V" will be incorrectly translated if V is an exception instance.
+The correct Python 3 idiom is ::
+   
+    raise E from V
+        
+but since we can't detect instance-hood by syntax alone and since any client
+code would have to be changed as well, we don't automate this.
+
+Another translation problem is this: ::
+
+    t = ((E, E2), E3)
+    raise t
+    
+2to3 has no way of knowing that t is a tuple, and so this code will raise an
+exception at runtime since the ability to raise tuples is going away.
+
+
+Notes
+=====
+
+.. [#1] I modified tokenize.py to yield a NL pseudo-token for backslash
+        continuations, so the original source can be reproduced exactly.  The
+        modified version can be found at lib2to3/pgen2/tokenize.py.
+
+.. [#2] I developed pgen2 while I was at Elemental Security.  I modified
+        it while at Google to suit the needs of this refactoring tool.
+
+
+Development
+===========
+
+The HACKING file has a list of TODOs -- some simple, some complex -- that would
+make good introductions for anyone new to 2to3.
+
+
+Licensing
+=========
+
+The original pgen2 module is copyrighted by Elemental Security.  All
+new code I wrote specifically for this tool is copyrighted by Google.
+New code by others is copyrighted by the respective authors.  All code
+(whether by me or by others) is licensed to the PSF under a contributor
+agreement.
+
+--Guido van Rossum
+
+
+All code I wrote specifically for this tool before 9 April 2007 is
+copyrighted by me. All new code I wrote specifically for this tool after
+9 April 2007 is copyrighted by Google. Regardless, my contributions are
+licensed to the PSF under a contributor agreement.
+
+--Collin Winter
+
+All of my contributions are copyrighted to me and licensed to PSF under the
+Python contributor agreement.
+
+--Benjamin Peterson
diff --git a/lib3/2to3/example.py b/lib3/2to3/example.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/example.py
@@ -0,0 +1,405 @@
+#!/usr/bin/python
+	# comment indented by tab
+
+"""Docstring.
+
+Here are some doctest exampes:
+
+>>> print 42
+42
+
+ >>> d = {1: 1, 2: 2, 2: 2}
+ >>> d.keys().sort()
+ >>> print d
+ {1: 1, 2: 2}
+
+  >>> for i in d.keys():
+  ...     print i, d[i]
+
+And a tricky one:
+
+>>> class X(Structure):
+...     _fields_ = [("x", c_int), ("y", c_int), ("array", c_char_p * 5)]
+...
+>>> x = X()
+>>> print x._objects
+None
+>>>
+
+"""
+
+import sys
+
+def unicode_examples():
+    a = str(b)
+    a = "xxx"
+    a = """xxx"""
+    a = r'xxx'
+    a = R'''xxx'''
+    a = r"xxx"
+    a = R"""xxx"""
+    b = "..." '...'
+
+def ne_examples():
+    if x != y:
+        pass
+    if x!=y:
+        pass
+    if x!=y!=z:
+        pass
+
+def has_key_examples():
+    #
+    x = "x" in d or "y" in d
+    #
+    x = ("x" in a.b.c.d) ** 3
+    #
+    x = (1 + 2 in a.b).__repr__()
+    #
+    x = (1 + 2 in a.b).__repr__() ** -3 ** 4
+    #
+    x = (f or g) in a
+    #
+    x = a + (c in b)
+    #
+    x = (lambda: 12) in a
+    #
+    x = (a for a in b) in a
+    #
+    if b not in a: pass
+    #
+    if not (b in a).__repr__(): pass
+    #
+    if not (b in a) ** 2: pass
+
+def foo():
+	pass # body indented by tab
+
+def test_ws_comma():
+    yield 1,2 ,3
+    f(1,2 ,3)
+    repr((a ,b))
+    def f(a,b ,c): pass
+    { a:b,c:d , e : f }
+
+def apply_examples():
+    x = f(*g + h)
+    y = f(*g, **h)
+    z = fs[0](*g or h, **h or g)
+    # Hello
+    f(*(x, y) + t)
+    f(*args)
+    f(*args, **kwds)
+    # Test that complex functions are parenthesized
+    x = (f+g)(*args)
+    x = (f*g)(*args)
+    x = (f**g)(*args)
+    # But dotted names etc. not
+    x = f.g(*args)
+    x = f[x](*args)
+    x = f()(*args)
+    # Extreme case
+    x = a.b.c.d.e.f(*args, **kwds)
+    # XXX Comments in weird places still get lost
+    f(*args)
+
+def bad_apply_examples():
+    # These should *not* be touched
+    apply()
+    apply(f)
+    apply(f,)
+    apply(f, args, kwds, extras)
+    apply(f, *args, **kwds)
+    apply(f, *args)
+    apply(func=f, args=args, kwds=kwds)
+    apply(f, args=args, kwds=kwds)
+    apply(f, args, kwds=kwds)
+
+def metaclass_examples():
+    class X(metaclass=Meta):
+        pass
+
+    class X(b1, b2, metaclass=Meta):
+        bar = 23 # Comment on me!
+        spam = 27.23 # Laughable
+
+    class X(metaclass=Meta):
+        x = 23; y = 34 # Yes, I can handle this, too.
+
+def intern_examples():
+    #
+    # These should be refactored:
+    #
+    x = sys.intern(a)
+    #
+    y = sys.intern("b" # test
+              )
+    #
+    z = sys.intern(a+b+c.d,)
+    #
+    sys.intern("y%s" % 5).replace("y", "")
+    #
+    # These not:
+    #
+    intern(a=1)
+    #
+    intern(f, g)
+    #
+    intern(*h)
+    #
+    intern(**i)
+
+def print_examples():
+    # plain vanilla
+    print(1, 1+1, 1+1+1)
+    #
+    print(1, 2)
+    #
+    print(1)
+
+    print()
+
+    # trailing commas
+    print(1, 2, 3, end=' ')
+    #
+    print(1, 2, end=' ')
+    #
+    print(1, end=' ')
+    #
+    print()
+
+    # >> stuff
+    print(1, 2, 3, file=sys.stderr)    # no trailing comma
+    #
+    print(1, 2, end=' ', file=sys.stdder)      # trailing comma
+    #
+    print(1+1, file=sys.stderr)        # no trailing comma
+    #
+    print(file=sys.stderr)           # spaces before sys.stderr
+
+def exec_examples():
+    #
+    exec(code)
+    #
+    exec(code, ns)
+    #
+    exec(code, ns1, ns2)
+    #
+    exec((a.b()), ns)
+    #
+    exec(a.b() + c, ns)
+    #
+    # These should not be touched:
+    #
+    exec(code)
+    #
+    exec (code)
+    #
+    exec(code, ns)
+    #
+    exec(code, ns1, ns2)
+
+def repr_examples():
+    x = repr(1 + 2)
+    #
+    y = repr(x)
+    #
+    z = repr(y).__repr__()
+    #
+    x = repr((1, 2, 3))
+    #
+    x = repr(1 + repr(2))
+    #
+    x = repr((1, 2 + repr((3, 4))))
+
+def except_examples():
+    try:
+        pass
+    except Exception as xxx_todo_changeme:
+        (f, e) = xxx_todo_changeme.args
+        pass
+    except ImportError as e:
+        print(e.args)
+    #
+    try:
+        pass
+    except (RuntimeError, ImportError) as e:
+        pass
+    #
+    try:
+        pass
+    except Exception as xxx_todo_changeme1:
+        (a, b) = xxx_todo_changeme1.args
+        pass
+    #
+    try:
+        pass
+    except Exception as xxx_todo_changeme2:
+        d[5] = xxx_todo_changeme2
+        pass
+    #
+    try:
+        pass
+    except Exception as xxx_todo_changeme3:
+        a.foo = xxx_todo_changeme3
+        pass
+    #
+    try:
+        pass
+    except Exception as xxx_todo_changeme4:
+        a().foo = xxx_todo_changeme4
+        pass
+    #
+    # These should not be touched:
+    #
+    try:
+        pass
+    except:
+        pass
+    #
+    try:
+        pass
+    except Exception:
+        pass
+    #
+    try:
+        pass
+    except (Exception, SystemExit):
+        pass
+
+def raise_examples():
+    raise Exception(5)
+    #
+    raise Exception(5)
+    #
+    raise Exception(5, 6, 7)
+    #
+    # These should not be touched
+    #
+    raise Exception
+    #
+    raise Exception(5, 6)
+    #
+    # These should produce a warning
+    # TODO: convert "raise E, V, T" to
+    #  "e = E(V); e.__traceback__ = T; raise e;"
+    #
+    raise Exception(5).with_traceback(6)
+    #
+    raise Exception(5).with_traceback(6)
+    #
+    raise Exception(5, 6, 7).with_traceback(6)
+
+def long_examples():
+    x = int(x)
+    y = isinstance(x, int)
+    z = type(x) in (int, int)
+    a = 12
+    b = 0x12
+    # unchanged:
+    a = 12
+    b = 0x12
+    c = 3.14
+
+def dict_examples():
+    #
+    # Plain method calls
+    #
+    print(list(d.keys()))
+    print(list(d.items()))
+    print(list(d.values()))
+    #
+    # Plain method calls in special contexts
+    #
+    print(iter(list(e.keys())))
+    for i in list(e.keys()): print(i)
+    [i for i in list(e.keys())]
+    (i for i in list(e.keys()))
+    #
+    # Iterator method calls
+    #
+    print(iter(f.keys()))
+    print(iter(f.items()))
+    print(iter(f.values()))
+    #
+    # Iterator method calls in special contexts
+    #
+    print(list(g.keys()))
+    print(sorted(g.keys()))
+    print(iter(g.keys()))
+    for i in g.keys(): print(i)
+    [i for i in g.keys()]
+    (i for i in g.keys())
+    #
+    # Examples with a "tail"; these are never "special"
+    #
+    print(next(iter(h.keys())))
+    print(list(h.keys())[0])
+    print(list(next(iter(h.keys()))))
+    for x in list(h.keys())[0]: print(x)
+    #
+    # Examples with dict views
+    #
+    print(d.keys())
+    print(d.items())
+    print(d.values())
+
+def dict_negative_examples():
+    #
+    # These should all remain unchanged:
+    #
+    print(list(h.keys()))
+    print(sorted(h.keys()))
+
+def xrange_examples():
+    for i in range(100): print(i)
+    for i in range(0, 100): print(i)
+    for i in range(0, 100, 10): print(i)
+
+def input_examples():
+    a = eval(input())
+    b = eval(input(str(a)))
+
+def raw_input_examples():
+    a = input()
+    b = input(a.rstrip())
+
+def filter_examples():
+    list(filter(os.unlink, filenames))
+    [_f for _f in "whatever" if _f]
+    [x for x in range(4) if not x]
+
+def map_examples():
+    list(map(None, foo.bar))
+    list(map(None, foo.bar,))
+    list(map(None, foo, bar))
+    list(map(f, foo.bar))
+    list(map(lambda x: x+1, list(range(10))))
+
+def basestring_examples():
+    if isinstance(x, str): pass
+
+def buffer_examples():
+    x = buffer(y)
+
+def sys_exc_examples():
+    print(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2])
+
+def operator_examples():
+    import operator
+    hasattr(foo, '__call__')
+    operator.contains(foo, bar)
+
+    from operator import isCallable, sequenceIncludes
+    # These should produce warnings.
+    isCallable(foo)
+    sequenceIncludes(foo, bar)
+
+class X:
+    def maximum(self):
+        return max(self.data.values())
+    def total(self):
+        return sum(self.data.values())
+
+
+# This is the last line.
diff --git a/lib3/2to3/lib2to3/Grammar.txt b/lib3/2to3/lib2to3/Grammar.txt
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/Grammar.txt
@@ -0,0 +1,158 @@
+# Grammar for Python
+
+# Note:  Changing the grammar specified in this file will most likely
+#        require corresponding changes in the parser module
+#        (../Modules/parsermodule.c).  If you can't make the changes to
+#        that module yourself, please co-ordinate the required changes
+#        with someone who can; ask around on python-dev for help.  Fred
+#        Drake <fdrake at acm.org> will probably be listening there.
+
+# NOTE WELL: You should also follow all the steps listed in PEP 306,
+# "How to Change Python's Grammar"
+
+# Commands for Kees Blom's railroad program
+#diagram:token NAME
+#diagram:token NUMBER
+#diagram:token STRING
+#diagram:token NEWLINE
+#diagram:token ENDMARKER
+#diagram:token INDENT
+#diagram:output\input python.bla
+#diagram:token DEDENT
+#diagram:output\textwidth 20.04cm\oddsidemargin  0.0cm\evensidemargin 0.0cm
+#diagram:rules
+
+# Start symbols for the grammar:
+#	file_input is a module or sequence of commands read from an input file;
+#	single_input is a single interactive statement;
+#	eval_input is the input for the eval() and input() functions.
+# NB: compound_stmt in single_input is followed by extra NEWLINE!
+file_input: (NEWLINE | stmt)* ENDMARKER
+single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+eval_input: testlist NEWLINE* ENDMARKER
+
+decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+decorators: decorator+
+decorated: decorators (classdef | funcdef)
+funcdef: 'def' NAME parameters ['->' test] ':' suite
+parameters: '(' [typedargslist] ')'
+typedargslist: ((tfpdef ['=' test] ',')*
+                ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname)
+                | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
+tname: NAME [':' test]
+tfpdef: tname | '(' tfplist ')'
+tfplist: tfpdef (',' tfpdef)* [',']
+varargslist: ((vfpdef ['=' test] ',')*
+              ('*' [vname] (',' vname ['=' test])*  [',' '**' vname] | '**' vname)
+              | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+vname: NAME
+vfpdef: vname | '(' vfplist ')'
+vfplist: vfpdef (',' vfpdef)* [',']
+
+stmt: simple_stmt | compound_stmt
+simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
+small_stmt: (expr_stmt | print_stmt  | del_stmt | pass_stmt | flow_stmt |
+             import_stmt | global_stmt | exec_stmt | assert_stmt)
+expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) |
+                     ('=' (yield_expr|testlist_star_expr))*)
+testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
+augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' |
+            '<<=' | '>>=' | '**=' | '//=')
+# For normal assignments, additional restrictions enforced by the interpreter
+print_stmt: 'print' ( [ test (',' test)* [','] ] |
+                      '>>' test [ (',' test)+ [','] ] )
+del_stmt: 'del' exprlist
+pass_stmt: 'pass'
+flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
+break_stmt: 'break'
+continue_stmt: 'continue'
+return_stmt: 'return' [testlist]
+yield_stmt: yield_expr
+raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]]
+import_stmt: import_name | import_from
+import_name: 'import' dotted_as_names
+import_from: ('from' ('.'* dotted_name | '.'+)
+              'import' ('*' | '(' import_as_names ')' | import_as_names))
+import_as_name: NAME ['as' NAME]
+dotted_as_name: dotted_name ['as' NAME]
+import_as_names: import_as_name (',' import_as_name)* [',']
+dotted_as_names: dotted_as_name (',' dotted_as_name)*
+dotted_name: NAME ('.' NAME)*
+global_stmt: ('global' | 'nonlocal') NAME (',' NAME)*
+exec_stmt: 'exec' expr ['in' test [',' test]]
+assert_stmt: 'assert' test [',' test]
+
+compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated
+if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+while_stmt: 'while' test ':' suite ['else' ':' suite]
+for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
+try_stmt: ('try' ':' suite
+           ((except_clause ':' suite)+
+	    ['else' ':' suite]
+	    ['finally' ':' suite] |
+	   'finally' ':' suite))
+with_stmt: 'with' with_item (',' with_item)*  ':' suite
+with_item: test ['as' expr]
+with_var: 'as' expr
+# NB compile.c makes sure that the default except clause is last
+except_clause: 'except' [test [(',' | 'as') test]]
+suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
+
+# Backward compatibility cruft to support:
+# [ x for x in lambda: True, lambda: False if x() ]
+# even while also allowing:
+# lambda x: 5 if x else 2
+# (But not a mix of the two)
+testlist_safe: old_test [(',' old_test)+ [',']]
+old_test: or_test | old_lambdef
+old_lambdef: 'lambda' [varargslist] ':' old_test
+
+test: or_test ['if' or_test 'else' test] | lambdef
+or_test: and_test ('or' and_test)*
+and_test: not_test ('and' not_test)*
+not_test: 'not' not_test | comparison
+comparison: expr (comp_op expr)*
+comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+star_expr: '*' expr
+expr: xor_expr ('|' xor_expr)*
+xor_expr: and_expr ('^' and_expr)*
+and_expr: shift_expr ('&' shift_expr)*
+shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+arith_expr: term (('+'|'-') term)*
+term: factor (('*'|'/'|'%'|'//') factor)*
+factor: ('+'|'-'|'~') factor | power
+power: atom trailer* ['**' factor]
+atom: ('(' [yield_expr|testlist_gexp] ')' |
+       '[' [listmaker] ']' |
+       '{' [dictsetmaker] '}' |
+       '`' testlist1 '`' |
+       NAME | NUMBER | STRING+ | '.' '.' '.')
+listmaker: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
+testlist_gexp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
+lambdef: 'lambda' [varargslist] ':' test
+trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+subscriptlist: subscript (',' subscript)* [',']
+subscript: test | [test] ':' [test] [sliceop]
+sliceop: ':' [test]
+exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
+testlist: test (',' test)* [',']
+dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) |
+                (test (comp_for | (',' test)* [','])) )
+
+classdef: 'class' NAME ['(' [arglist] ')'] ':' suite
+
+arglist: (argument ',')* (argument [',']
+                         |'*' test (',' argument)* [',' '**' test] 
+                         |'**' test)
+argument: test [comp_for] | test '=' test  # Really [keyword '='] test
+
+comp_iter: comp_for | comp_if
+comp_for: 'for' exprlist 'in' testlist_safe [comp_iter]
+comp_if: 'if' old_test [comp_iter]
+
+testlist1: test (',' test)*
+
+# not used in grammar, but may appear in "node" passed from Parser to Compiler
+encoding_decl: NAME
+
+yield_expr: 'yield' [testlist]
diff --git a/lib3/2to3/lib2to3/Grammar3.3.2.final.0.pickle b/lib3/2to3/lib2to3/Grammar3.3.2.final.0.pickle
new file mode 100644
index 0000000000000000000000000000000000000000..75b6ed97f37c891e7bf59e87bc4d9b00f8dc2220
GIT binary patch
[stripped]
diff --git a/lib3/2to3/lib2to3/Grammar3.4.0.alpha.1.pickle b/lib3/2to3/lib2to3/Grammar3.4.0.alpha.1.pickle
new file mode 100644
index 0000000000000000000000000000000000000000..47538c4926776fb9cfca46f5b012954416fe1ccd
GIT binary patch
[stripped]
diff --git a/lib3/2to3/lib2to3/PatternGrammar.txt b/lib3/2to3/lib2to3/PatternGrammar.txt
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/PatternGrammar.txt
@@ -0,0 +1,28 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# A grammar to describe tree matching patterns.
+# Not shown here:
+# - 'TOKEN' stands for any token (leaf node)
+# - 'any' stands for any node (leaf or interior)
+# With 'any' we can still specify the sub-structure.
+
+# The start symbol is 'Matcher'.
+
+Matcher: Alternatives ENDMARKER
+
+Alternatives: Alternative ('|' Alternative)*
+
+Alternative: (Unit | NegatedUnit)+
+
+Unit: [NAME '='] ( STRING [Repeater]
+                 | NAME [Details] [Repeater]
+                 | '(' Alternatives ')' [Repeater]
+                 | '[' Alternatives ']'
+		 )
+
+NegatedUnit: 'not' (STRING | NAME [Details] | '(' Alternatives ')')
+
+Repeater: '*' | '+' | '{' NUMBER [',' NUMBER] '}'
+
+Details: '<' Alternatives '>'
diff --git a/lib3/2to3/lib2to3/PatternGrammar3.3.2.final.0.pickle b/lib3/2to3/lib2to3/PatternGrammar3.3.2.final.0.pickle
new file mode 100644
index 0000000000000000000000000000000000000000..65c9c657879b3059c16e7db1168a1a823b529f65
GIT binary patch
[stripped]
diff --git a/lib3/2to3/lib2to3/PatternGrammar3.4.0.alpha.1.pickle b/lib3/2to3/lib2to3/PatternGrammar3.4.0.alpha.1.pickle
new file mode 100644
index 0000000000000000000000000000000000000000..92ba51d6585b371200989ad68c00eb74858f43e1
GIT binary patch
[stripped]
diff --git a/lib3/2to3/lib2to3/__init__.py b/lib3/2to3/lib2to3/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/__init__.py
@@ -0,0 +1,1 @@
+#empty
diff --git a/lib3/2to3/lib2to3/btm_matcher.py b/lib3/2to3/lib2to3/btm_matcher.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/btm_matcher.py
@@ -0,0 +1,168 @@
+"""A bottom-up tree matching algorithm implementation meant to speed
+up 2to3's matching process. After the tree patterns are reduced to
+their rarest linear path, a linear Aho-Corasick automaton is
+created. The linear automaton traverses the linear paths from the
+leaves to the root of the AST and returns a set of nodes for further
+matching. This reduces significantly the number of candidate nodes."""
+
+__author__ = "George Boutsioukis <gboutsioukis at gmail.com>"
+
+import logging
+import itertools
+from collections import defaultdict
+
+from . import pytree
+from .btm_utils import reduce_tree
+
+class BMNode(object):
+    """Class for a node of the Aho-Corasick automaton used in matching"""
+    count = itertools.count()
+    def __init__(self):
+        self.transition_table = {}
+        self.fixers = []
+        self.id = next(BMNode.count)
+        self.content = ''
+
+class BottomMatcher(object):
+    """The main matcher class. After instantiating the patterns should
+    be added using the add_fixer method"""
+
+    def __init__(self):
+        self.match = set()
+        self.root = BMNode()
+        self.nodes = [self.root]
+        self.fixers = []
+        self.logger = logging.getLogger("RefactoringTool")
+
+    def add_fixer(self, fixer):
+        """Reduces a fixer's pattern tree to a linear path and adds it
+        to the matcher(a common Aho-Corasick automaton). The fixer is
+        appended on the matching states and called when they are
+        reached"""
+        self.fixers.append(fixer)
+        tree = reduce_tree(fixer.pattern_tree)
+        linear = tree.get_linear_subpattern()
+        match_nodes = self.add(linear, start=self.root)
+        for match_node in match_nodes:
+            match_node.fixers.append(fixer)
+
+    def add(self, pattern, start):
+        "Recursively adds a linear pattern to the AC automaton"
+        #print("adding pattern", pattern, "to", start)
+        if not pattern:
+            #print("empty pattern")
+            return [start]
+        if isinstance(pattern[0], tuple):
+            #alternatives
+            #print("alternatives")
+            match_nodes = []
+            for alternative in pattern[0]:
+                #add all alternatives, and add the rest of the pattern
+                #to each end node
+                end_nodes = self.add(alternative, start=start)
+                for end in end_nodes:
+                    match_nodes.extend(self.add(pattern[1:], end))
+            return match_nodes
+        else:
+            #single token
+            #not last
+            if pattern[0] not in start.transition_table:
+                #transition did not exist, create new
+                next_node = BMNode()
+                start.transition_table[pattern[0]] = next_node
+            else:
+                #transition exists already, follow
+                next_node = start.transition_table[pattern[0]]
+
+            if pattern[1:]:
+                end_nodes = self.add(pattern[1:], start=next_node)
+            else:
+                end_nodes = [next_node]
+            return end_nodes
+
+    def run(self, leaves):
+        """The main interface with the bottom matcher. The tree is
+        traversed from the bottom using the constructed
+        automaton. Nodes are only checked once as the tree is
+        retraversed. When the automaton fails, we give it one more
+        shot(in case the above tree matches as a whole with the
+        rejected leaf), then we break for the next leaf. There is the
+        special case of multiple arguments(see code comments) where we
+        recheck the nodes
+
+        Args:
+           The leaves of the AST tree to be matched
+
+        Returns:
+           A dictionary of node matches with fixers as the keys
+        """
+        current_ac_node = self.root
+        results = defaultdict(list)
+        for leaf in leaves:
+            current_ast_node = leaf
+            while current_ast_node:
+                current_ast_node.was_checked = True
+                for child in current_ast_node.children:
+                    # multiple statements, recheck
+                    if isinstance(child, pytree.Leaf) and child.value == ";":
+                        current_ast_node.was_checked = False
+                        break
+                if current_ast_node.type == 1:
+                    #name
+                    node_token = current_ast_node.value
+                else:
+                    node_token = current_ast_node.type
+
+                if node_token in current_ac_node.transition_table:
+                    #token matches
+                    current_ac_node = current_ac_node.transition_table[node_token]
+                    for fixer in current_ac_node.fixers:
+                        if not fixer in results:
+                            results[fixer] = []
+                        results[fixer].append(current_ast_node)
+
+                else:
+                    #matching failed, reset automaton
+                    current_ac_node = self.root
+                    if (current_ast_node.parent is not None
+                        and current_ast_node.parent.was_checked):
+                        #the rest of the tree upwards has been checked, next leaf
+                        break
+
+                    #recheck the rejected node once from the root
+                    if node_token in current_ac_node.transition_table:
+                        #token matches
+                        current_ac_node = current_ac_node.transition_table[node_token]
+                        for fixer in current_ac_node.fixers:
+                            if not fixer in list(results.keys()):
+                                results[fixer] = []
+                            results[fixer].append(current_ast_node)
+
+                current_ast_node = current_ast_node.parent
+        return results
+
+    def print_ac(self):
+        "Prints a graphviz diagram of the BM automaton(for debugging)"
+        print("digraph g{")
+        def print_node(node):
+            for subnode_key in list(node.transition_table.keys()):
+                subnode = node.transition_table[subnode_key]
+                print(("%d -> %d [label=%s] //%s" %
+                      (node.id, subnode.id, type_repr(subnode_key), str(subnode.fixers))))
+                if subnode_key == 1:
+                    print((subnode.content))
+                print_node(subnode)
+        print_node(self.root)
+        print("}")
+
+# taken from pytree.py for debugging; only used by print_ac
+_type_reprs = {}
+def type_repr(type_num):
+    global _type_reprs
+    if not _type_reprs:
+        from .pygram import python_symbols
+        # printing tokens is possible but not as useful
+        # from .pgen2 import token // token.__dict__.items():
+        for name, val in list(python_symbols.__dict__.items()):
+            if type(val) == int: _type_reprs[val] = name
+    return _type_reprs.setdefault(type_num, type_num)
diff --git a/lib3/2to3/lib2to3/btm_utils.py b/lib3/2to3/lib2to3/btm_utils.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/btm_utils.py
@@ -0,0 +1,283 @@
+"Utility functions used by the btm_matcher module"
+
+from . import pytree
+from .pgen2 import grammar, token
+from .pygram import pattern_symbols, python_symbols
+
+syms = pattern_symbols
+pysyms = python_symbols
+tokens = grammar.opmap
+token_labels = token
+
+TYPE_ANY = -1
+TYPE_ALTERNATIVES = -2
+TYPE_GROUP = -3
+
+class MinNode(object):
+    """This class serves as an intermediate representation of the
+    pattern tree during the conversion to sets of leaf-to-root
+    subpatterns"""
+
+    def __init__(self, type=None, name=None):
+        self.type = type
+        self.name = name
+        self.children = []
+        self.leaf = False
+        self.parent = None
+        self.alternatives = []
+        self.group = []
+
+    def __repr__(self):
+        return str(self.type) + ' ' + str(self.name)
+
+    def leaf_to_root(self):
+        """Internal method. Returns a characteristic path of the
+        pattern tree. This method must be run for all leaves until the
+        linear subpatterns are merged into a single"""
+        node = self
+        subp = []
+        while node:
+            if node.type == TYPE_ALTERNATIVES:
+                node.alternatives.append(subp)
+                if len(node.alternatives) == len(node.children):
+                    #last alternative
+                    subp = [tuple(node.alternatives)]
+                    node.alternatives = []
+                    node = node.parent
+                    continue
+                else:
+                    node = node.parent
+                    subp = None
+                    break
+
+            if node.type == TYPE_GROUP:
+                node.group.append(subp)
+                #probably should check the number of leaves
+                if len(node.group) == len(node.children):
+                    subp = get_characteristic_subpattern(node.group)
+                    node.group = []
+                    node = node.parent
+                    continue
+                else:
+                    node = node.parent
+                    subp = None
+                    break
+
+            if node.type == token_labels.NAME and node.name:
+                #in case of type=name, use the name instead
+                subp.append(node.name)
+            else:
+                subp.append(node.type)
+
+            node = node.parent
+        return subp
+
+    def get_linear_subpattern(self):
+        """Drives the leaf_to_root method. The reason that
+        leaf_to_root must be run multiple times is because we need to
+        reject 'group' matches; for example the alternative form
+        (a | b c) creates a group [b c] that needs to be matched. Since
+        matching multiple linear patterns overcomes the automaton's
+        capabilities, leaf_to_root merges each group into a single
+        choice based on 'characteristic'ity,
+
+        i.e. (a|b c) -> (a|b) if b more characteristic than c
+
+        Returns: The most 'characteristic'(as defined by
+          get_characteristic_subpattern) path for the compiled pattern
+          tree.
+        """
+
+        for l in self.leaves():
+            subp = l.leaf_to_root()
+            if subp:
+                return subp
+
+    def leaves(self):
+        "Generator that returns the leaves of the tree"
+        for child in self.children:
+            for x in child.leaves():
+                yield x
+        if not self.children:
+            yield self
+
+def reduce_tree(node, parent=None):
+    """
+    Internal function. Reduces a compiled pattern tree to an
+    intermediate representation suitable for feeding the
+    automaton. This also trims off any optional pattern elements(like
+    [a], a*).
+    """
+
+    new_node = None
+    #switch on the node type
+    if node.type == syms.Matcher:
+        #skip
+        node = node.children[0]
+
+    if node.type == syms.Alternatives  :
+        #2 cases
+        if len(node.children) <= 2:
+            #just a single 'Alternative', skip this node
+            new_node = reduce_tree(node.children[0], parent)
+        else:
+            #real alternatives
+            new_node = MinNode(type=TYPE_ALTERNATIVES)
+            #skip odd children('|' tokens)
+            for child in node.children:
+                if node.children.index(child)%2:
+                    continue
+                reduced = reduce_tree(child, new_node)
+                if reduced is not None:
+                    new_node.children.append(reduced)
+    elif node.type == syms.Alternative:
+        if len(node.children) > 1:
+
+            new_node = MinNode(type=TYPE_GROUP)
+            for child in node.children:
+                reduced = reduce_tree(child, new_node)
+                if reduced:
+                    new_node.children.append(reduced)
+            if not new_node.children:
+                # delete the group if all of the children were reduced to None
+                new_node = None
+
+        else:
+            new_node = reduce_tree(node.children[0], parent)
+
+    elif node.type == syms.Unit:
+        if (isinstance(node.children[0], pytree.Leaf) and
+            node.children[0].value == '('):
+            #skip parentheses
+            return reduce_tree(node.children[1], parent)
+        if ((isinstance(node.children[0], pytree.Leaf) and
+               node.children[0].value == '[')
+               or
+               (len(node.children)>1 and
+               hasattr(node.children[1], "value") and
+               node.children[1].value == '[')):
+            #skip whole unit if its optional
+            return None
+
+        leaf = True
+        details_node = None
+        alternatives_node = None
+        has_repeater = False
+        repeater_node = None
+        has_variable_name = False
+
+        for child in node.children:
+            if child.type == syms.Details:
+                leaf = False
+                details_node = child
+            elif child.type == syms.Repeater:
+                has_repeater = True
+                repeater_node = child
+            elif child.type == syms.Alternatives:
+                alternatives_node = child
+            if hasattr(child, 'value') and child.value == '=': # variable name
+                has_variable_name = True
+
+        #skip variable name
+        if has_variable_name:
+            #skip variable name, '='
+            name_leaf = node.children[2]
+            if hasattr(name_leaf, 'value') and name_leaf.value == '(':
+                # skip parenthesis
+                name_leaf = node.children[3]
+        else:
+            name_leaf = node.children[0]
+
+        #set node type
+        if name_leaf.type == token_labels.NAME:
+            #(python) non-name or wildcard
+            if name_leaf.value == 'any':
+                new_node = MinNode(type=TYPE_ANY)
+            else:
+                if hasattr(token_labels, name_leaf.value):
+                    new_node = MinNode(type=getattr(token_labels, name_leaf.value))
+                else:
+                    new_node = MinNode(type=getattr(pysyms, name_leaf.value))
+
+        elif name_leaf.type == token_labels.STRING:
+            #(python) name or character; remove the apostrophes from
+            #the string value
+            name = name_leaf.value.strip("'")
+            if name in tokens:
+                new_node = MinNode(type=tokens[name])
+            else:
+                new_node = MinNode(type=token_labels.NAME, name=name)
+        elif name_leaf.type == syms.Alternatives:
+            new_node = reduce_tree(alternatives_node, parent)
+
+        #handle repeaters
+        if has_repeater:
+            if repeater_node.children[0].value == '*':
+                #reduce to None
+                new_node = None
+            elif repeater_node.children[0].value == '+':
+                #reduce to a single occurence i.e. do nothing
+                pass
+            else:
+                #TODO: handle {min, max} repeaters
+                raise NotImplementedError
+                pass
+
+        #add children
+        if details_node and new_node is not None:
+            for child in details_node.children[1:-1]:
+                #skip '<', '>' markers
+                reduced = reduce_tree(child, new_node)
+                if reduced is not None:
+                    new_node.children.append(reduced)
+    if new_node:
+        new_node.parent = parent
+    return new_node
+
+
+def get_characteristic_subpattern(subpatterns):
+    """Picks the most characteristic from a list of linear patterns
+    Current order used is:
+    names > common_names > common_chars
+    """
+    if not isinstance(subpatterns, list):
+        return subpatterns
+    if len(subpatterns)==1:
+        return subpatterns[0]
+
+    # first pick out the ones containing variable names
+    subpatterns_with_names = []
+    subpatterns_with_common_names = []
+    common_names = ['in', 'for', 'if' , 'not', 'None']
+    subpatterns_with_common_chars = []
+    common_chars = "[]().,:"
+    for subpattern in subpatterns:
+        if any(rec_test(subpattern, lambda x: type(x) is str)):
+            if any(rec_test(subpattern,
+                            lambda x: isinstance(x, str) and x in common_chars)):
+                subpatterns_with_common_chars.append(subpattern)
+            elif any(rec_test(subpattern,
+                              lambda x: isinstance(x, str) and x in common_names)):
+                subpatterns_with_common_names.append(subpattern)
+
+            else:
+                subpatterns_with_names.append(subpattern)
+
+    if subpatterns_with_names:
+        subpatterns = subpatterns_with_names
+    elif subpatterns_with_common_names:
+        subpatterns = subpatterns_with_common_names
+    elif subpatterns_with_common_chars:
+        subpatterns = subpatterns_with_common_chars
+    # of the remaining subpatterns pick out the longest one
+    return max(subpatterns, key=len)
+
+def rec_test(sequence, test_func):
+    """Tests test_func on all items of sequence and items of included
+    sub-iterables"""
+    for x in sequence:
+        if isinstance(x, (list, tuple)):
+            for y in rec_test(x, test_func):
+                yield y
+        else:
+            yield test_func(x)
diff --git a/lib3/2to3/lib2to3/fixer_base.py b/lib3/2to3/lib2to3/fixer_base.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixer_base.py
@@ -0,0 +1,189 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Base class for fixers (optional, but recommended)."""
+
+# Python imports
+import logging
+import itertools
+
+# Local imports
+from .patcomp import PatternCompiler
+from . import pygram
+from .fixer_util import does_tree_import
+
+class BaseFix(object):
+
+    """Optional base class for fixers.
+
+    The subclass name must be FixFooBar where FooBar is the result of
+    removing underscores and capitalizing the words of the fix name.
+    For example, the class name for a fixer named 'has_key' should be
+    FixHasKey.
+    """
+
+    PATTERN = None  # Most subclasses should override with a string literal
+    pattern = None  # Compiled pattern, set by compile_pattern()
+    pattern_tree = None # Tree representation of the pattern
+    options = None  # Options object passed to initializer
+    filename = None # The filename (set by set_filename)
+    logger = None   # A logger (set by set_filename)
+    numbers = itertools.count(1) # For new_name()
+    used_names = set() # A set of all used NAMEs
+    order = "post" # Does the fixer prefer pre- or post-order traversal
+    explicit = False # Is this ignored by refactor.py -f all?
+    run_order = 5   # Fixers will be sorted by run order before execution
+                    # Lower numbers will be run first.
+    _accept_type = None # [Advanced and not public] This tells RefactoringTool
+                        # which node type to accept when there's not a pattern.
+
+    keep_line_order = False # For the bottom matcher: match with the
+                            # original line order
+    BM_compatible = False # Compatibility with the bottom matching
+                          # module; every fixer should set this
+                          # manually
+
+    # Shortcut for access to Python grammar symbols
+    syms = pygram.python_symbols
+
+    def __init__(self, options, log):
+        """Initializer.  Subclass may override.
+
+        Args:
+            options: an dict containing the options passed to RefactoringTool
+            that could be used to customize the fixer through the command line.
+            log: a list to append warnings and other messages to.
+        """
+        self.options = options
+        self.log = log
+        self.compile_pattern()
+
+    def compile_pattern(self):
+        """Compiles self.PATTERN into self.pattern.
+
+        Subclass may override if it doesn't want to use
+        self.{pattern,PATTERN} in .match().
+        """
+        if self.PATTERN is not None:
+            PC = PatternCompiler()
+            self.pattern, self.pattern_tree = PC.compile_pattern(self.PATTERN,
+                                                                 with_tree=True)
+
+    def set_filename(self, filename):
+        """Set the filename, and a logger derived from it.
+
+        The main refactoring tool should call this.
+        """
+        self.filename = filename
+        self.logger = logging.getLogger(filename)
+
+    def match(self, node):
+        """Returns match for a given parse tree node.
+
+        Should return a true or false object (not necessarily a bool).
+        It may return a non-empty dict of matching sub-nodes as
+        returned by a matching pattern.
+
+        Subclass may override.
+        """
+        results = {"node": node}
+        return self.pattern.match(node, results) and results
+
+    def transform(self, node, results):
+        """Returns the transformation for a given parse tree node.
+
+        Args:
+          node: the root of the parse tree that matched the fixer.
+          results: a dict mapping symbolic names to part of the match.
+
+        Returns:
+          None, or a node that is a modified copy of the
+          argument node.  The node argument may also be modified in-place to
+          effect the same change.
+
+        Subclass *must* override.
+        """
+        raise NotImplementedError()
+
+    def new_name(self, template="xxx_todo_changeme"):
+        """Return a string suitable for use as an identifier
+
+        The new name is guaranteed not to conflict with other identifiers.
+        """
+        name = template
+        while name in self.used_names:
+            name = template + str(next(self.numbers))
+        self.used_names.add(name)
+        return name
+
+    def log_message(self, message):
+        if self.first_log:
+            self.first_log = False
+            self.log.append("### In file %s ###" % self.filename)
+        self.log.append(message)
+
+    def cannot_convert(self, node, reason=None):
+        """Warn the user that a given chunk of code is not valid Python 3,
+        but that it cannot be converted automatically.
+
+        First argument is the top-level node for the code in question.
+        Optional second argument is why it can't be converted.
+        """
+        lineno = node.get_lineno()
+        for_output = node.clone()
+        for_output.prefix = ""
+        msg = "Line %d: could not convert: %s"
+        self.log_message(msg % (lineno, for_output))
+        if reason:
+            self.log_message(reason)
+
+    def warning(self, node, reason):
+        """Used for warning the user about possible uncertainty in the
+        translation.
+
+        First argument is the top-level node for the code in question.
+        Optional second argument is why it can't be converted.
+        """
+        lineno = node.get_lineno()
+        self.log_message("Line %d: %s" % (lineno, reason))
+
+    def start_tree(self, tree, filename):
+        """Some fixers need to maintain tree-wide state.
+        This method is called once, at the start of tree fix-up.
+
+        tree - the root node of the tree to be processed.
+        filename - the name of the file the tree came from.
+        """
+        self.used_names = tree.used_names
+        self.set_filename(filename)
+        self.numbers = itertools.count(1)
+        self.first_log = True
+
+    def finish_tree(self, tree, filename):
+        """Some fixers need to maintain tree-wide state.
+        This method is called once, at the conclusion of tree fix-up.
+
+        tree - the root node of the tree to be processed.
+        filename - the name of the file the tree came from.
+        """
+        pass
+
+
+class ConditionalFix(BaseFix):
+    """ Base class for fixers which not execute if an import is found. """
+
+    # This is the name of the import which, if found, will cause the test to be skipped
+    skip_on = None
+
+    def start_tree(self, *args):
+        super(ConditionalFix, self).start_tree(*args)
+        self._should_skip = None
+
+    def should_skip(self, node):
+        if self._should_skip is not None:
+            return self._should_skip
+        pkg = self.skip_on.split(".")
+        name = pkg[-1]
+        pkg = ".".join(pkg[:-1])
+        self._should_skip = does_tree_import(pkg, name, node)
+        return self._should_skip
diff --git a/lib3/2to3/lib2to3/fixer_util.py b/lib3/2to3/lib2to3/fixer_util.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixer_util.py
@@ -0,0 +1,432 @@
+"""Utility functions, node construction macros, etc."""
+# Author: Collin Winter
+
+from itertools import islice
+
+# Local imports
+from .pgen2 import token
+from .pytree import Leaf, Node
+from .pygram import python_symbols as syms
+from . import patcomp
+
+
+###########################################################
+### Common node-construction "macros"
+###########################################################
+
+def KeywordArg(keyword, value):
+    return Node(syms.argument,
+                [keyword, Leaf(token.EQUAL, "="), value])
+
+def LParen():
+    return Leaf(token.LPAR, "(")
+
+def RParen():
+    return Leaf(token.RPAR, ")")
+
+def Assign(target, source):
+    """Build an assignment statement"""
+    if not isinstance(target, list):
+        target = [target]
+    if not isinstance(source, list):
+        source.prefix = " "
+        source = [source]
+
+    return Node(syms.atom,
+                target + [Leaf(token.EQUAL, "=", prefix=" ")] + source)
+
+def Name(name, prefix=None):
+    """Return a NAME leaf"""
+    return Leaf(token.NAME, name, prefix=prefix)
+
+def Attr(obj, attr):
+    """A node tuple for obj.attr"""
+    return [obj, Node(syms.trailer, [Dot(), attr])]
+
+def Comma():
+    """A comma leaf"""
+    return Leaf(token.COMMA, ",")
+
+def Dot():
+    """A period (.) leaf"""
+    return Leaf(token.DOT, ".")
+
+def ArgList(args, lparen=LParen(), rparen=RParen()):
+    """A parenthesised argument list, used by Call()"""
+    node = Node(syms.trailer, [lparen.clone(), rparen.clone()])
+    if args:
+        node.insert_child(1, Node(syms.arglist, args))
+    return node
+
+def Call(func_name, args=None, prefix=None):
+    """A function call"""
+    node = Node(syms.power, [func_name, ArgList(args)])
+    if prefix is not None:
+        node.prefix = prefix
+    return node
+
+def Newline():
+    """A newline literal"""
+    return Leaf(token.NEWLINE, "\n")
+
+def BlankLine():
+    """A blank line"""
+    return Leaf(token.NEWLINE, "")
+
+def Number(n, prefix=None):
+    return Leaf(token.NUMBER, n, prefix=prefix)
+
+def Subscript(index_node):
+    """A numeric or string subscript"""
+    return Node(syms.trailer, [Leaf(token.LBRACE, "["),
+                               index_node,
+                               Leaf(token.RBRACE, "]")])
+
+def String(string, prefix=None):
+    """A string leaf"""
+    return Leaf(token.STRING, string, prefix=prefix)
+
+def ListComp(xp, fp, it, test=None):
+    """A list comprehension of the form [xp for fp in it if test].
+
+    If test is None, the "if test" part is omitted.
+    """
+    xp.prefix = ""
+    fp.prefix = " "
+    it.prefix = " "
+    for_leaf = Leaf(token.NAME, "for")
+    for_leaf.prefix = " "
+    in_leaf = Leaf(token.NAME, "in")
+    in_leaf.prefix = " "
+    inner_args = [for_leaf, fp, in_leaf, it]
+    if test:
+        test.prefix = " "
+        if_leaf = Leaf(token.NAME, "if")
+        if_leaf.prefix = " "
+        inner_args.append(Node(syms.comp_if, [if_leaf, test]))
+    inner = Node(syms.listmaker, [xp, Node(syms.comp_for, inner_args)])
+    return Node(syms.atom,
+                       [Leaf(token.LBRACE, "["),
+                        inner,
+                        Leaf(token.RBRACE, "]")])
+
+def FromImport(package_name, name_leafs):
+    """ Return an import statement in the form:
+        from package import name_leafs"""
+    # XXX: May not handle dotted imports properly (eg, package_name='foo.bar')
+    #assert package_name == '.' or '.' not in package_name, "FromImport has "\
+    #       "not been tested with dotted package names -- use at your own "\
+    #       "peril!"
+
+    for leaf in name_leafs:
+        # Pull the leaves out of their old tree
+        leaf.remove()
+
+    children = [Leaf(token.NAME, "from"),
+                Leaf(token.NAME, package_name, prefix=" "),
+                Leaf(token.NAME, "import", prefix=" "),
+                Node(syms.import_as_names, name_leafs)]
+    imp = Node(syms.import_from, children)
+    return imp
+
+
+###########################################################
+### Determine whether a node represents a given literal
+###########################################################
+
+def is_tuple(node):
+    """Does the node represent a tuple literal?"""
+    if isinstance(node, Node) and node.children == [LParen(), RParen()]:
+        return True
+    return (isinstance(node, Node)
+            and len(node.children) == 3
+            and isinstance(node.children[0], Leaf)
+            and isinstance(node.children[1], Node)
+            and isinstance(node.children[2], Leaf)
+            and node.children[0].value == "("
+            and node.children[2].value == ")")
+
+def is_list(node):
+    """Does the node represent a list literal?"""
+    return (isinstance(node, Node)
+            and len(node.children) > 1
+            and isinstance(node.children[0], Leaf)
+            and isinstance(node.children[-1], Leaf)
+            and node.children[0].value == "["
+            and node.children[-1].value == "]")
+
+
+###########################################################
+### Misc
+###########################################################
+
+def parenthesize(node):
+    return Node(syms.atom, [LParen(), node, RParen()])
+
+
+consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum",
+                       "min", "max"])
+
+def attr_chain(obj, attr):
+    """Follow an attribute chain.
+
+    If you have a chain of objects where a.foo -> b, b.foo-> c, etc,
+    use this to iterate over all objects in the chain. Iteration is
+    terminated by getattr(x, attr) is None.
+
+    Args:
+        obj: the starting object
+        attr: the name of the chaining attribute
+
+    Yields:
+        Each successive object in the chain.
+    """
+    next = getattr(obj, attr)
+    while next:
+        yield next
+        next = getattr(next, attr)
+
+p0 = """for_stmt< 'for' any 'in' node=any ':' any* >
+        | comp_for< 'for' any 'in' node=any any* >
+     """
+p1 = """
+power<
+    ( 'iter' | 'list' | 'tuple' | 'sorted' | 'set' | 'sum' |
+      'any' | 'all' | (any* trailer< '.' 'join' >) )
+    trailer< '(' node=any ')' >
+    any*
+>
+"""
+p2 = """
+power<
+    'sorted'
+    trailer< '(' arglist<node=any any*> ')' >
+    any*
+>
+"""
+pats_built = False
+def in_special_context(node):
+    """ Returns true if node is in an environment where all that is required
+        of it is being itterable (ie, it doesn't matter if it returns a list
+        or an itterator).
+        See test_map_nochange in test_fixers.py for some examples and tests.
+        """
+    global p0, p1, p2, pats_built
+    if not pats_built:
+        p1 = patcomp.compile_pattern(p1)
+        p0 = patcomp.compile_pattern(p0)
+        p2 = patcomp.compile_pattern(p2)
+        pats_built = True
+    patterns = [p0, p1, p2]
+    for pattern, parent in zip(patterns, attr_chain(node, "parent")):
+        results = {}
+        if pattern.match(parent, results) and results["node"] is node:
+            return True
+    return False
+
+def is_probably_builtin(node):
+    """
+    Check that something isn't an attribute or function name etc.
+    """
+    prev = node.prev_sibling
+    if prev is not None and prev.type == token.DOT:
+        # Attribute lookup.
+        return False
+    parent = node.parent
+    if parent.type in (syms.funcdef, syms.classdef):
+        return False
+    if parent.type == syms.expr_stmt and parent.children[0] is node:
+        # Assignment.
+        return False
+    if parent.type == syms.parameters or \
+            (parent.type == syms.typedargslist and (
+            (prev is not None and prev.type == token.COMMA) or
+            parent.children[0] is node
+            )):
+        # The name of an argument.
+        return False
+    return True
+
+def find_indentation(node):
+    """Find the indentation of *node*."""
+    while node is not None:
+        if node.type == syms.suite and len(node.children) > 2:
+            indent = node.children[1]
+            if indent.type == token.INDENT:
+                return indent.value
+        node = node.parent
+    return ""
+
+###########################################################
+### The following functions are to find bindings in a suite
+###########################################################
+
+def make_suite(node):
+    if node.type == syms.suite:
+        return node
+    node = node.clone()
+    parent, node.parent = node.parent, None
+    suite = Node(syms.suite, [node])
+    suite.parent = parent
+    return suite
+
+def find_root(node):
+    """Find the top level namespace."""
+    # Scamper up to the top level namespace
+    while node.type != syms.file_input:
+        assert node.parent, "Tree is insane! root found before "\
+                           "file_input node was found."
+        node = node.parent
+    return node
+
+def does_tree_import(package, name, node):
+    """ Returns true if name is imported from package at the
+        top level of the tree which node belongs to.
+        To cover the case of an import like 'import foo', use
+        None for the package and 'foo' for the name. """
+    binding = find_binding(name, find_root(node), package)
+    return bool(binding)
+
+def is_import(node):
+    """Returns true if the node is an import statement."""
+    return node.type in (syms.import_name, syms.import_from)
+
+def touch_import(package, name, node):
+    """ Works like `does_tree_import` but adds an import statement
+        if it was not imported. """
+    def is_import_stmt(node):
+        return (node.type == syms.simple_stmt and node.children and
+                is_import(node.children[0]))
+
+    root = find_root(node)
+
+    if does_tree_import(package, name, root):
+        return
+
+    # figure out where to insert the new import.  First try to find
+    # the first import and then skip to the last one.
+    insert_pos = offset = 0
+    for idx, node in enumerate(root.children):
+        if not is_import_stmt(node):
+            continue
+        for offset, node2 in enumerate(root.children[idx:]):
+            if not is_import_stmt(node2):
+                break
+        insert_pos = idx + offset
+        break
+
+    # if there are no imports where we can insert, find the docstring.
+    # if that also fails, we stick to the beginning of the file
+    if insert_pos == 0:
+        for idx, node in enumerate(root.children):
+            if (node.type == syms.simple_stmt and node.children and
+               node.children[0].type == token.STRING):
+                insert_pos = idx + 1
+                break
+
+    if package is None:
+        import_ = Node(syms.import_name, [
+            Leaf(token.NAME, "import"),
+            Leaf(token.NAME, name, prefix=" ")
+        ])
+    else:
+        import_ = FromImport(package, [Leaf(token.NAME, name, prefix=" ")])
+
+    children = [import_, Newline()]
+    root.insert_child(insert_pos, Node(syms.simple_stmt, children))
+
+
+_def_syms = set([syms.classdef, syms.funcdef])
+def find_binding(name, node, package=None):
+    """ Returns the node which binds variable name, otherwise None.
+        If optional argument package is supplied, only imports will
+        be returned.
+        See test cases for examples."""
+    for child in node.children:
+        ret = None
+        if child.type == syms.for_stmt:
+            if _find(name, child.children[1]):
+                return child
+            n = find_binding(name, make_suite(child.children[-1]), package)
+            if n: ret = n
+        elif child.type in (syms.if_stmt, syms.while_stmt):
+            n = find_binding(name, make_suite(child.children[-1]), package)
+            if n: ret = n
+        elif child.type == syms.try_stmt:
+            n = find_binding(name, make_suite(child.children[2]), package)
+            if n:
+                ret = n
+            else:
+                for i, kid in enumerate(child.children[3:]):
+                    if kid.type == token.COLON and kid.value == ":":
+                        # i+3 is the colon, i+4 is the suite
+                        n = find_binding(name, make_suite(child.children[i+4]), package)
+                        if n: ret = n
+        elif child.type in _def_syms and child.children[1].value == name:
+            ret = child
+        elif _is_import_binding(child, name, package):
+            ret = child
+        elif child.type == syms.simple_stmt:
+            ret = find_binding(name, child, package)
+        elif child.type == syms.expr_stmt:
+            if _find(name, child.children[0]):
+                ret = child
+
+        if ret:
+            if not package:
+                return ret
+            if is_import(ret):
+                return ret
+    return None
+
+_block_syms = set([syms.funcdef, syms.classdef, syms.trailer])
+def _find(name, node):
+    nodes = [node]
+    while nodes:
+        node = nodes.pop()
+        if node.type > 256 and node.type not in _block_syms:
+            nodes.extend(node.children)
+        elif node.type == token.NAME and node.value == name:
+            return node
+    return None
+
+def _is_import_binding(node, name, package=None):
+    """ Will reuturn node if node will import name, or node
+        will import * from package.  None is returned otherwise.
+        See test cases for examples. """
+
+    if node.type == syms.import_name and not package:
+        imp = node.children[1]
+        if imp.type == syms.dotted_as_names:
+            for child in imp.children:
+                if child.type == syms.dotted_as_name:
+                    if child.children[2].value == name:
+                        return node
+                elif child.type == token.NAME and child.value == name:
+                    return node
+        elif imp.type == syms.dotted_as_name:
+            last = imp.children[-1]
+            if last.type == token.NAME and last.value == name:
+                return node
+        elif imp.type == token.NAME and imp.value == name:
+            return node
+    elif node.type == syms.import_from:
+        # unicode(...) is used to make life easier here, because
+        # from a.b import parses to ['import', ['a', '.', 'b'], ...]
+        if package and str(node.children[1]).strip() != package:
+            return None
+        n = node.children[3]
+        if package and _find("as", n):
+            # See test_from_import_as for explanation
+            return None
+        elif n.type == syms.import_as_names and _find(name, n):
+            return node
+        elif n.type == syms.import_as_name:
+            child = n.children[2]
+            if child.type == token.NAME and child.value == name:
+                return node
+        elif n.type == token.NAME and n.value == name:
+            return node
+        elif package and n.type == token.STAR:
+            return node
+    return None
diff --git a/lib3/2to3/lib2to3/fixes/__init__.py b/lib3/2to3/lib2to3/fixes/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/__init__.py
@@ -0,0 +1,1 @@
+# Dummy file to make this directory a package.
diff --git a/lib3/2to3/lib2to3/fixes/fix_apply.py b/lib3/2to3/lib2to3/fixes/fix_apply.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_apply.py
@@ -0,0 +1,59 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for apply().
+
+This converts apply(func, v, k) into (func)(*v, **k)."""
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Call, Comma, parenthesize
+
+class FixApply(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+    power< 'apply'
+        trailer<
+            '('
+            arglist<
+                (not argument<NAME '=' any>) func=any ','
+                (not argument<NAME '=' any>) args=any [','
+                (not argument<NAME '=' any>) kwds=any] [',']
+            >
+            ')'
+        >
+    >
+    """
+
+    def transform(self, node, results):
+        syms = self.syms
+        assert results
+        func = results["func"]
+        args = results["args"]
+        kwds = results.get("kwds")
+        prefix = node.prefix
+        func = func.clone()
+        if (func.type not in (token.NAME, syms.atom) and
+            (func.type != syms.power or
+             func.children[-2].type == token.DOUBLESTAR)):
+            # Need to parenthesize
+            func = parenthesize(func)
+        func.prefix = ""
+        args = args.clone()
+        args.prefix = ""
+        if kwds is not None:
+            kwds = kwds.clone()
+            kwds.prefix = ""
+        l_newargs = [pytree.Leaf(token.STAR, "*"), args]
+        if kwds is not None:
+            l_newargs.extend([Comma(),
+                              pytree.Leaf(token.DOUBLESTAR, "**"),
+                              kwds])
+            l_newargs[-2].prefix = " " # that's the ** token
+        # XXX Sometimes we could be cleverer, e.g. apply(f, (x, y) + t)
+        # can be translated into f(x, y, *t) instead of f(*(x, y) + t)
+        #new = pytree.Node(syms.power, (func, ArgList(l_newargs)))
+        return Call(func, l_newargs, prefix=prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_basestring.py b/lib3/2to3/lib2to3/fixes/fix_basestring.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_basestring.py
@@ -0,0 +1,14 @@
+"""Fixer for basestring -> str."""
+# Author: Christian Heimes
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+class FixBasestring(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = "'basestring'"
+
+    def transform(self, node, results):
+        return Name("str", prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_buffer.py b/lib3/2to3/lib2to3/fixes/fix_buffer.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_buffer.py
@@ -0,0 +1,22 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that changes buffer(...) into memoryview(...)."""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+
+class FixBuffer(fixer_base.BaseFix):
+    BM_compatible = True
+
+    explicit = True # The user must ask for this fixer
+
+    PATTERN = """
+              power< name='buffer' trailer< '(' [any] ')' > any* >
+              """
+
+    def transform(self, node, results):
+        name = results["name"]
+        name.replace(Name("memoryview", prefix=name.prefix))
diff --git a/lib3/2to3/lib2to3/fixes/fix_callable.py b/lib3/2to3/lib2to3/fixes/fix_callable.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_callable.py
@@ -0,0 +1,37 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for callable().
+
+This converts callable(obj) into isinstance(obj, collections.Callable), adding a
+collections import if needed."""
+
+# Local imports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import Call, Name, String, Attr, touch_import
+
+class FixCallable(fixer_base.BaseFix):
+    BM_compatible = True
+
+    order = "pre"
+
+    # Ignore callable(*args) or use of keywords.
+    # Either could be a hint that the builtin callable() is not being used.
+    PATTERN = """
+    power< 'callable'
+           trailer< lpar='('
+                    ( not(arglist | argument<any '=' any>) func=any
+                      | func=arglist<(not argument<any '=' any>) any ','> )
+                    rpar=')' >
+           after=any*
+    >
+    """
+
+    def transform(self, node, results):
+        func = results['func']
+
+        touch_import(None, 'collections', node=node)
+
+        args = [func.clone(), String(', ')]
+        args.extend(Attr(Name('collections'), Name('Callable')))
+        return Call(Name('isinstance'), args, prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_dict.py b/lib3/2to3/lib2to3/fixes/fix_dict.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_dict.py
@@ -0,0 +1,107 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for dict methods.
+
+d.keys() -> list(d.keys())
+d.items() -> list(d.items())
+d.values() -> list(d.values())
+
+d.iterkeys() -> iter(d.keys())
+d.iteritems() -> iter(d.items())
+d.itervalues() -> iter(d.values())
+
+d.viewkeys() -> d.keys()
+d.viewitems() -> d.items()
+d.viewvalues() -> d.values()
+
+Except in certain very specific contexts: the iter() can be dropped
+when the context is list(), sorted(), iter() or for...in; the list()
+can be dropped when the context is list() or sorted() (but not iter()
+or for...in!). Special contexts that apply to both: list(), sorted(), tuple()
+set(), any(), all(), sum().
+
+Note: iter(d.keys()) could be written as iter(d) but since the
+original d.iterkeys() was also redundant we don't fix this.  And there
+are (rare) contexts where it makes a difference (e.g. when passing it
+as an argument to a function that introspects the argument).
+"""
+
+# Local imports
+from .. import pytree
+from .. import patcomp
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, LParen, RParen, ArgList, Dot
+from .. import fixer_util
+
+
+iter_exempt = fixer_util.consuming_calls | set(["iter"])
+
+
+class FixDict(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+    power< head=any+
+         trailer< '.' method=('keys'|'items'|'values'|
+                              'iterkeys'|'iteritems'|'itervalues'|
+                              'viewkeys'|'viewitems'|'viewvalues') >
+         parens=trailer< '(' ')' >
+         tail=any*
+    >
+    """
+
+    def transform(self, node, results):
+        head = results["head"]
+        method = results["method"][0] # Extract node for method name
+        tail = results["tail"]
+        syms = self.syms
+        method_name = method.value
+        isiter = method_name.startswith("iter")
+        isview = method_name.startswith("view")
+        if isiter or isview:
+            method_name = method_name[4:]
+        assert method_name in ("keys", "items", "values"), repr(method)
+        head = [n.clone() for n in head]
+        tail = [n.clone() for n in tail]
+        special = not tail and self.in_special_context(node, isiter)
+        args = head + [pytree.Node(syms.trailer,
+                                   [Dot(),
+                                    Name(method_name,
+                                         prefix=method.prefix)]),
+                       results["parens"].clone()]
+        new = pytree.Node(syms.power, args)
+        if not (special or isview):
+            new.prefix = ""
+            new = Call(Name("iter" if isiter else "list"), [new])
+        if tail:
+            new = pytree.Node(syms.power, [new] + tail)
+        new.prefix = node.prefix
+        return new
+
+    P1 = "power< func=NAME trailer< '(' node=any ')' > any* >"
+    p1 = patcomp.compile_pattern(P1)
+
+    P2 = """for_stmt< 'for' any 'in' node=any ':' any* >
+            | comp_for< 'for' any 'in' node=any any* >
+         """
+    p2 = patcomp.compile_pattern(P2)
+
+    def in_special_context(self, node, isiter):
+        if node.parent is None:
+            return False
+        results = {}
+        if (node.parent.parent is not None and
+               self.p1.match(node.parent.parent, results) and
+               results["node"] is node):
+            if isiter:
+                # iter(d.iterkeys()) -> iter(d.keys()), etc.
+                return results["func"].value in iter_exempt
+            else:
+                # list(d.keys()) -> list(d.keys()), etc.
+                return results["func"].value in fixer_util.consuming_calls
+        if not isiter:
+            return False
+        # for ... in d.iterkeys() -> for ... in d.keys(), etc.
+        return self.p2.match(node.parent, results) and results["node"] is node
diff --git a/lib3/2to3/lib2to3/fixes/fix_except.py b/lib3/2to3/lib2to3/fixes/fix_except.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_except.py
@@ -0,0 +1,93 @@
+"""Fixer for except statements with named exceptions.
+
+The following cases will be converted:
+
+- "except E, T:" where T is a name:
+
+    except E as T:
+
+- "except E, T:" where T is not a name, tuple or list:
+
+        except E as t:
+            T = t
+
+    This is done because the target of an "except" clause must be a
+    name.
+
+- "except E, T:" where T is a tuple or list literal:
+
+        except E as t:
+            T = t.args
+"""
+# Author: Collin Winter
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Assign, Attr, Name, is_tuple, is_list, syms
+
+def find_excepts(nodes):
+    for i, n in enumerate(nodes):
+        if n.type == syms.except_clause:
+            if n.children[0].value == 'except':
+                yield (n, nodes[i+2])
+
+class FixExcept(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+    try_stmt< 'try' ':' (simple_stmt | suite)
+                  cleanup=(except_clause ':' (simple_stmt | suite))+
+                  tail=(['except' ':' (simple_stmt | suite)]
+                        ['else' ':' (simple_stmt | suite)]
+                        ['finally' ':' (simple_stmt | suite)]) >
+    """
+
+    def transform(self, node, results):
+        syms = self.syms
+
+        tail = [n.clone() for n in results["tail"]]
+
+        try_cleanup = [ch.clone() for ch in results["cleanup"]]
+        for except_clause, e_suite in find_excepts(try_cleanup):
+            if len(except_clause.children) == 4:
+                (E, comma, N) = except_clause.children[1:4]
+                comma.replace(Name("as", prefix=" "))
+
+                if N.type != token.NAME:
+                    # Generate a new N for the except clause
+                    new_N = Name(self.new_name(), prefix=" ")
+                    target = N.clone()
+                    target.prefix = ""
+                    N.replace(new_N)
+                    new_N = new_N.clone()
+
+                    # Insert "old_N = new_N" as the first statement in
+                    #  the except body. This loop skips leading whitespace
+                    #  and indents
+                    #TODO(cwinter) suite-cleanup
+                    suite_stmts = e_suite.children
+                    for i, stmt in enumerate(suite_stmts):
+                        if isinstance(stmt, pytree.Node):
+                            break
+
+                    # The assignment is different if old_N is a tuple or list
+                    # In that case, the assignment is old_N = new_N.args
+                    if is_tuple(N) or is_list(N):
+                        assign = Assign(target, Attr(new_N, Name('args')))
+                    else:
+                        assign = Assign(target, new_N)
+
+                    #TODO(cwinter) stopgap until children becomes a smart list
+                    for child in reversed(suite_stmts[:i]):
+                        e_suite.insert_child(0, child)
+                    e_suite.insert_child(i, assign)
+                elif N.prefix == "":
+                    # No space after a comma is legal; no space after "as",
+                    # not so much.
+                    N.prefix = " "
+
+        #TODO(cwinter) fix this when children becomes a smart list
+        children = [c.clone() for c in node.children[:3]] + try_cleanup + tail
+        return pytree.Node(node.type, children)
diff --git a/lib3/2to3/lib2to3/fixes/fix_exec.py b/lib3/2to3/lib2to3/fixes/fix_exec.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_exec.py
@@ -0,0 +1,40 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for exec.
+
+This converts usages of the exec statement into calls to a built-in
+exec() function.
+
+exec code in ns1, ns2 -> exec(code, ns1, ns2)
+"""
+
+# Local imports
+from .. import pytree
+from .. import fixer_base
+from ..fixer_util import Comma, Name, Call
+
+
+class FixExec(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+    exec_stmt< 'exec' a=any 'in' b=any [',' c=any] >
+    |
+    exec_stmt< 'exec' (not atom<'(' [any] ')'>) a=any >
+    """
+
+    def transform(self, node, results):
+        assert results
+        syms = self.syms
+        a = results["a"]
+        b = results.get("b")
+        c = results.get("c")
+        args = [a.clone()]
+        args[0].prefix = ""
+        if b is not None:
+            args.extend([Comma(), b.clone()])
+        if c is not None:
+            args.extend([Comma(), c.clone()])
+
+        return Call(Name("exec"), args, prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_execfile.py b/lib3/2to3/lib2to3/fixes/fix_execfile.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_execfile.py
@@ -0,0 +1,52 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for execfile.
+
+This converts usages of the execfile function into calls to the built-in
+exec() function.
+"""
+
+from .. import fixer_base
+from ..fixer_util import (Comma, Name, Call, LParen, RParen, Dot, Node,
+                          ArgList, String, syms)
+
+
+class FixExecfile(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+    power< 'execfile' trailer< '(' arglist< filename=any [',' globals=any [',' locals=any ] ] > ')' > >
+    |
+    power< 'execfile' trailer< '(' filename=any ')' > >
+    """
+
+    def transform(self, node, results):
+        assert results
+        filename = results["filename"]
+        globals = results.get("globals")
+        locals = results.get("locals")
+
+        # Copy over the prefix from the right parentheses end of the execfile
+        # call.
+        execfile_paren = node.children[-1].children[-1].clone()
+        # Construct open().read().
+        open_args = ArgList([filename.clone()], rparen=execfile_paren)
+        open_call = Node(syms.power, [Name("open"), open_args])
+        read = [Node(syms.trailer, [Dot(), Name('read')]),
+                Node(syms.trailer, [LParen(), RParen()])]
+        open_expr = [open_call] + read
+        # Wrap the open call in a compile call. This is so the filename will be
+        # preserved in the execed code.
+        filename_arg = filename.clone()
+        filename_arg.prefix = " "
+        exec_str = String("'exec'", " ")
+        compile_args = open_expr + [Comma(), filename_arg, Comma(), exec_str]
+        compile_call = Call(Name("compile"), compile_args, "")
+        # Finally, replace the execfile call with an exec call.
+        args = [compile_call]
+        if globals is not None:
+            args.extend([Comma(), globals.clone()])
+        if locals is not None:
+            args.extend([Comma(), locals.clone()])
+        return Call(Name("exec"), args, prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_exitfunc.py b/lib3/2to3/lib2to3/fixes/fix_exitfunc.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_exitfunc.py
@@ -0,0 +1,72 @@
+"""
+Convert use of sys.exitfunc to use the atexit module.
+"""
+
+# Author: Benjamin Peterson
+
+from lib2to3 import pytree, fixer_base
+from lib2to3.fixer_util import Name, Attr, Call, Comma, Newline, syms
+
+
+class FixExitfunc(fixer_base.BaseFix):
+    keep_line_order = True
+    BM_compatible = True
+
+    PATTERN = """
+              (
+                  sys_import=import_name<'import'
+                      ('sys'
+                      |
+                      dotted_as_names< (any ',')* 'sys' (',' any)* >
+                      )
+                  >
+              |
+                  expr_stmt<
+                      power< 'sys' trailer< '.' 'exitfunc' > >
+                  '=' func=any >
+              )
+              """
+
+    def __init__(self, *args):
+        super(FixExitfunc, self).__init__(*args)
+
+    def start_tree(self, tree, filename):
+        super(FixExitfunc, self).start_tree(tree, filename)
+        self.sys_import = None
+
+    def transform(self, node, results):
+        # First, find a the sys import. We'll just hope it's global scope.
+        if "sys_import" in results:
+            if self.sys_import is None:
+                self.sys_import = results["sys_import"]
+            return
+
+        func = results["func"].clone()
+        func.prefix = ""
+        register = pytree.Node(syms.power,
+                               Attr(Name("atexit"), Name("register"))
+                               )
+        call = Call(register, [func], node.prefix)
+        node.replace(call)
+
+        if self.sys_import is None:
+            # That's interesting.
+            self.warning(node, "Can't find sys import; Please add an atexit "
+                             "import at the top of your file.")
+            return
+
+        # Now add an atexit import after the sys import.
+        names = self.sys_import.children[1]
+        if names.type == syms.dotted_as_names:
+            names.append_child(Comma())
+            names.append_child(Name("atexit", " "))
+        else:
+            containing_stmt = self.sys_import.parent
+            position = containing_stmt.children.index(self.sys_import)
+            stmt_container = containing_stmt.parent
+            new_import = pytree.Node(syms.import_name,
+                              [Name("import"), Name("atexit", " ")]
+                              )
+            new = pytree.Node(syms.simple_stmt, [new_import])
+            containing_stmt.insert_child(position + 1, Newline())
+            containing_stmt.insert_child(position + 2, new)
diff --git a/lib3/2to3/lib2to3/fixes/fix_filter.py b/lib3/2to3/lib2to3/fixes/fix_filter.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_filter.py
@@ -0,0 +1,76 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that changes filter(F, X) into list(filter(F, X)).
+
+We avoid the transformation if the filter() call is directly contained
+in iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or
+for V in <>:.
+
+NOTE: This is still not correct if the original code was depending on
+filter(F, X) to return a string if X is a string and a tuple if X is a
+tuple.  That would require type inference, which we don't do.  Let
+Python 2.6 figure it out.
+"""
+
+# Local imports
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, ListComp, in_special_context
+
+class FixFilter(fixer_base.ConditionalFix):
+    BM_compatible = True
+
+    PATTERN = """
+    filter_lambda=power<
+        'filter'
+        trailer<
+            '('
+            arglist<
+                lambdef< 'lambda'
+                         (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any
+                >
+                ','
+                it=any
+            >
+            ')'
+        >
+    >
+    |
+    power<
+        'filter'
+        trailer< '(' arglist< none='None' ',' seq=any > ')' >
+    >
+    |
+    power<
+        'filter'
+        args=trailer< '(' [any] ')' >
+    >
+    """
+
+    skip_on = "future_builtins.filter"
+
+    def transform(self, node, results):
+        if self.should_skip(node):
+            return
+
+        if "filter_lambda" in results:
+            new = ListComp(results.get("fp").clone(),
+                           results.get("fp").clone(),
+                           results.get("it").clone(),
+                           results.get("xp").clone())
+
+        elif "none" in results:
+            new = ListComp(Name("_f"),
+                           Name("_f"),
+                           results["seq"].clone(),
+                           Name("_f"))
+
+        else:
+            if in_special_context(node):
+                return None
+            new = node.clone()
+            new.prefix = ""
+            new = Call(Name("list"), [new])
+        new.prefix = node.prefix
+        return new
diff --git a/lib3/2to3/lib2to3/fixes/fix_funcattrs.py b/lib3/2to3/lib2to3/fixes/fix_funcattrs.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_funcattrs.py
@@ -0,0 +1,21 @@
+"""Fix function attribute names (f.func_x -> f.__x__)."""
+# Author: Collin Winter
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+
+class FixFuncattrs(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+    power< any+ trailer< '.' attr=('func_closure' | 'func_doc' | 'func_globals'
+                                  | 'func_name' | 'func_defaults' | 'func_code'
+                                  | 'func_dict') > any* >
+    """
+
+    def transform(self, node, results):
+        attr = results["attr"][0]
+        attr.replace(Name(("__%s__" % attr.value[5:]),
+                          prefix=attr.prefix))
diff --git a/lib3/2to3/lib2to3/fixes/fix_future.py b/lib3/2to3/lib2to3/fixes/fix_future.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_future.py
@@ -0,0 +1,22 @@
+"""Remove __future__ imports
+
+from __future__ import foo is replaced with an empty line.
+"""
+# Author: Christian Heimes
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import BlankLine
+
+class FixFuture(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """import_from< 'from' module_name="__future__" 'import' any >"""
+
+    # This should be run last -- some things check for the import
+    run_order = 10
+
+    def transform(self, node, results):
+        new = BlankLine()
+        new.prefix = node.prefix
+        return new
diff --git a/lib3/2to3/lib2to3/fixes/fix_getcwdu.py b/lib3/2to3/lib2to3/fixes/fix_getcwdu.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_getcwdu.py
@@ -0,0 +1,19 @@
+"""
+Fixer that changes os.getcwdu() to os.getcwd().
+"""
+# Author: Victor Stinner
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+class FixGetcwdu(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+              power< 'os' trailer< dot='.' name='getcwdu' > any* >
+              """
+
+    def transform(self, node, results):
+        name = results["name"]
+        name.replace(Name("getcwd", prefix=name.prefix))
diff --git a/lib3/2to3/lib2to3/fixes/fix_has_key.py b/lib3/2to3/lib2to3/fixes/fix_has_key.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_has_key.py
@@ -0,0 +1,110 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for has_key().
+
+Calls to .has_key() methods are expressed in terms of the 'in'
+operator:
+
+    d.has_key(k) -> k in d
+
+CAVEATS:
+1) While the primary target of this fixer is dict.has_key(), the
+   fixer will change any has_key() method call, regardless of its
+   class.
+
+2) Cases like this will not be converted:
+
+    m = d.has_key
+    if m(k):
+        ...
+
+   Only *calls* to has_key() are converted. While it is possible to
+   convert the above to something like
+
+    m = d.__contains__
+    if m(k):
+        ...
+
+   this is currently not done.
+"""
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, parenthesize
+
+
+class FixHasKey(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+    anchor=power<
+        before=any+
+        trailer< '.' 'has_key' >
+        trailer<
+            '('
+            ( not(arglist | argument<any '=' any>) arg=any
+            | arglist<(not argument<any '=' any>) arg=any ','>
+            )
+            ')'
+        >
+        after=any*
+    >
+    |
+    negation=not_test<
+        'not'
+        anchor=power<
+            before=any+
+            trailer< '.' 'has_key' >
+            trailer<
+                '('
+                ( not(arglist | argument<any '=' any>) arg=any
+                | arglist<(not argument<any '=' any>) arg=any ','>
+                )
+                ')'
+            >
+        >
+    >
+    """
+
+    def transform(self, node, results):
+        assert results
+        syms = self.syms
+        if (node.parent.type == syms.not_test and
+            self.pattern.match(node.parent)):
+            # Don't transform a node matching the first alternative of the
+            # pattern when its parent matches the second alternative
+            return None
+        negation = results.get("negation")
+        anchor = results["anchor"]
+        prefix = node.prefix
+        before = [n.clone() for n in results["before"]]
+        arg = results["arg"].clone()
+        after = results.get("after")
+        if after:
+            after = [n.clone() for n in after]
+        if arg.type in (syms.comparison, syms.not_test, syms.and_test,
+                        syms.or_test, syms.test, syms.lambdef, syms.argument):
+            arg = parenthesize(arg)
+        if len(before) == 1:
+            before = before[0]
+        else:
+            before = pytree.Node(syms.power, before)
+        before.prefix = " "
+        n_op = Name("in", prefix=" ")
+        if negation:
+            n_not = Name("not", prefix=" ")
+            n_op = pytree.Node(syms.comp_op, (n_not, n_op))
+        new = pytree.Node(syms.comparison, (arg, n_op, before))
+        if after:
+            new = parenthesize(new)
+            new = pytree.Node(syms.power, (new,) + tuple(after))
+        if node.parent.type in (syms.comparison, syms.expr, syms.xor_expr,
+                                syms.and_expr, syms.shift_expr,
+                                syms.arith_expr, syms.term,
+                                syms.factor, syms.power):
+            new = parenthesize(new)
+        new.prefix = prefix
+        return new
diff --git a/lib3/2to3/lib2to3/fixes/fix_idioms.py b/lib3/2to3/lib2to3/fixes/fix_idioms.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_idioms.py
@@ -0,0 +1,152 @@
+"""Adjust some old Python 2 idioms to their modern counterparts.
+
+* Change some type comparisons to isinstance() calls:
+    type(x) == T -> isinstance(x, T)
+    type(x) is T -> isinstance(x, T)
+    type(x) != T -> not isinstance(x, T)
+    type(x) is not T -> not isinstance(x, T)
+
+* Change "while 1:" into "while True:".
+
+* Change both
+
+    v = list(EXPR)
+    v.sort()
+    foo(v)
+
+and the more general
+
+    v = EXPR
+    v.sort()
+    foo(v)
+
+into
+
+    v = sorted(EXPR)
+    foo(v)
+"""
+# Author: Jacques Frechet, Collin Winter
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Call, Comma, Name, Node, BlankLine, syms
+
+CMP = "(n='!=' | '==' | 'is' | n=comp_op< 'is' 'not' >)"
+TYPE = "power< 'type' trailer< '(' x=any ')' > >"
+
+class FixIdioms(fixer_base.BaseFix):
+    explicit = True # The user must ask for this fixer
+
+    PATTERN = r"""
+        isinstance=comparison< %s %s T=any >
+        |
+        isinstance=comparison< T=any %s %s >
+        |
+        while_stmt< 'while' while='1' ':' any+ >
+        |
+        sorted=any<
+            any*
+            simple_stmt<
+              expr_stmt< id1=any '='
+                         power< list='list' trailer< '(' (not arglist<any+>) any ')' > >
+              >
+              '\n'
+            >
+            sort=
+            simple_stmt<
+              power< id2=any
+                     trailer< '.' 'sort' > trailer< '(' ')' >
+              >
+              '\n'
+            >
+            next=any*
+        >
+        |
+        sorted=any<
+            any*
+            simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' >
+            sort=
+            simple_stmt<
+              power< id2=any
+                     trailer< '.' 'sort' > trailer< '(' ')' >
+              >
+              '\n'
+            >
+            next=any*
+        >
+    """ % (TYPE, CMP, CMP, TYPE)
+
+    def match(self, node):
+        r = super(FixIdioms, self).match(node)
+        # If we've matched one of the sort/sorted subpatterns above, we
+        # want to reject matches where the initial assignment and the
+        # subsequent .sort() call involve different identifiers.
+        if r and "sorted" in r:
+            if r["id1"] == r["id2"]:
+                return r
+            return None
+        return r
+
+    def transform(self, node, results):
+        if "isinstance" in results:
+            return self.transform_isinstance(node, results)
+        elif "while" in results:
+            return self.transform_while(node, results)
+        elif "sorted" in results:
+            return self.transform_sort(node, results)
+        else:
+            raise RuntimeError("Invalid match")
+
+    def transform_isinstance(self, node, results):
+        x = results["x"].clone() # The thing inside of type()
+        T = results["T"].clone() # The type being compared against
+        x.prefix = ""
+        T.prefix = " "
+        test = Call(Name("isinstance"), [x, Comma(), T])
+        if "n" in results:
+            test.prefix = " "
+            test = Node(syms.not_test, [Name("not"), test])
+        test.prefix = node.prefix
+        return test
+
+    def transform_while(self, node, results):
+        one = results["while"]
+        one.replace(Name("True", prefix=one.prefix))
+
+    def transform_sort(self, node, results):
+        sort_stmt = results["sort"]
+        next_stmt = results["next"]
+        list_call = results.get("list")
+        simple_expr = results.get("expr")
+
+        if list_call:
+            list_call.replace(Name("sorted", prefix=list_call.prefix))
+        elif simple_expr:
+            new = simple_expr.clone()
+            new.prefix = ""
+            simple_expr.replace(Call(Name("sorted"), [new],
+                                     prefix=simple_expr.prefix))
+        else:
+            raise RuntimeError("should not have reached here")
+        sort_stmt.remove()
+
+        btwn = sort_stmt.prefix
+        # Keep any prefix lines between the sort_stmt and the list_call and
+        # shove them right after the sorted() call.
+        if "\n" in btwn:
+            if next_stmt:
+                # The new prefix should be everything from the sort_stmt's
+                # prefix up to the last newline, then the old prefix after a new
+                # line.
+                prefix_lines = (btwn.rpartition("\n")[0], next_stmt[0].prefix)
+                next_stmt[0].prefix = "\n".join(prefix_lines)
+            else:
+                assert list_call.parent
+                assert list_call.next_sibling is None
+                # Put a blank line after list_call and set its prefix.
+                end_line = BlankLine()
+                list_call.parent.append_child(end_line)
+                assert list_call.next_sibling is end_line
+                # The new prefix should be everything up to the first new line
+                # of sort_stmt's prefix.
+                end_line.prefix = btwn.rpartition("\n")[0]
diff --git a/lib3/2to3/lib2to3/fixes/fix_import.py b/lib3/2to3/lib2to3/fixes/fix_import.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_import.py
@@ -0,0 +1,99 @@
+"""Fixer for import statements.
+If spam is being imported from the local directory, this import:
+    from spam import eggs
+Becomes:
+    from .spam import eggs
+
+And this import:
+    import spam
+Becomes:
+    from . import spam
+"""
+
+# Local imports
+from .. import fixer_base
+from os.path import dirname, join, exists, sep
+from ..fixer_util import FromImport, syms, token
+
+
+def traverse_imports(names):
+    """
+    Walks over all the names imported in a dotted_as_names node.
+    """
+    pending = [names]
+    while pending:
+        node = pending.pop()
+        if node.type == token.NAME:
+            yield node.value
+        elif node.type == syms.dotted_name:
+            yield "".join([ch.value for ch in node.children])
+        elif node.type == syms.dotted_as_name:
+            pending.append(node.children[0])
+        elif node.type == syms.dotted_as_names:
+            pending.extend(node.children[::-2])
+        else:
+            raise AssertionError("unkown node type")
+
+
+class FixImport(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+    import_from< 'from' imp=any 'import' ['('] any [')'] >
+    |
+    import_name< 'import' imp=any >
+    """
+
+    def start_tree(self, tree, name):
+        super(FixImport, self).start_tree(tree, name)
+        self.skip = "absolute_import" in tree.future_features
+
+    def transform(self, node, results):
+        if self.skip:
+            return
+        imp = results['imp']
+
+        if node.type == syms.import_from:
+            # Some imps are top-level (eg: 'import ham')
+            # some are first level (eg: 'import ham.eggs')
+            # some are third level (eg: 'import ham.eggs as spam')
+            # Hence, the loop
+            while not hasattr(imp, 'value'):
+                imp = imp.children[0]
+            if self.probably_a_local_import(imp.value):
+                imp.value = "." + imp.value
+                imp.changed()
+        else:
+            have_local = False
+            have_absolute = False
+            for mod_name in traverse_imports(imp):
+                if self.probably_a_local_import(mod_name):
+                    have_local = True
+                else:
+                    have_absolute = True
+            if have_absolute:
+                if have_local:
+                    # We won't handle both sibling and absolute imports in the
+                    # same statement at the moment.
+                    self.warning(node, "absolute and local imports together")
+                return
+
+            new = FromImport(".", [imp])
+            new.prefix = node.prefix
+            return new
+
+    def probably_a_local_import(self, imp_name):
+        if imp_name.startswith("."):
+            # Relative imports are certainly not local imports.
+            return False
+        imp_name = imp_name.split(".", 1)[0]
+        base_path = dirname(self.filename)
+        base_path = join(base_path, imp_name)
+        # If there is no __init__.py next to the file its not in a package
+        # so can't be a relative import.
+        if not exists(join(dirname(base_path), "__init__.py")):
+            return False
+        for ext in [".py", sep, ".pyc", ".so", ".sl", ".pyd"]:
+            if exists(base_path + ext):
+                return True
+        return False
diff --git a/lib3/2to3/lib2to3/fixes/fix_imports.py b/lib3/2to3/lib2to3/fixes/fix_imports.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_imports.py
@@ -0,0 +1,145 @@
+"""Fix incompatible imports and module references."""
+# Authors: Collin Winter, Nick Edds
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, attr_chain
+
+MAPPING = {'StringIO':  'io',
+           'cStringIO': 'io',
+           'cPickle': 'pickle',
+           '__builtin__' : 'builtins',
+           'copy_reg': 'copyreg',
+           'Queue': 'queue',
+           'SocketServer': 'socketserver',
+           'ConfigParser': 'configparser',
+           'repr': 'reprlib',
+           'FileDialog': 'tkinter.filedialog',
+           'tkFileDialog': 'tkinter.filedialog',
+           'SimpleDialog': 'tkinter.simpledialog',
+           'tkSimpleDialog': 'tkinter.simpledialog',
+           'tkColorChooser': 'tkinter.colorchooser',
+           'tkCommonDialog': 'tkinter.commondialog',
+           'Dialog': 'tkinter.dialog',
+           'Tkdnd': 'tkinter.dnd',
+           'tkFont': 'tkinter.font',
+           'tkMessageBox': 'tkinter.messagebox',
+           'ScrolledText': 'tkinter.scrolledtext',
+           'Tkconstants': 'tkinter.constants',
+           'Tix': 'tkinter.tix',
+           'ttk': 'tkinter.ttk',
+           'Tkinter': 'tkinter',
+           'markupbase': '_markupbase',
+           '_winreg': 'winreg',
+           'thread': '_thread',
+           'dummy_thread': '_dummy_thread',
+           # anydbm and whichdb are handled by fix_imports2
+           'dbhash': 'dbm.bsd',
+           'dumbdbm': 'dbm.dumb',
+           'dbm': 'dbm.ndbm',
+           'gdbm': 'dbm.gnu',
+           'xmlrpclib': 'xmlrpc.client',
+           'DocXMLRPCServer': 'xmlrpc.server',
+           'SimpleXMLRPCServer': 'xmlrpc.server',
+           'httplib': 'http.client',
+           'htmlentitydefs' : 'html.entities',
+           'HTMLParser' : 'html.parser',
+           'Cookie': 'http.cookies',
+           'cookielib': 'http.cookiejar',
+           'BaseHTTPServer': 'http.server',
+           'SimpleHTTPServer': 'http.server',
+           'CGIHTTPServer': 'http.server',
+           #'test.test_support': 'test.support',
+           'commands': 'subprocess',
+           'UserString' : 'collections',
+           'UserList' : 'collections',
+           'urlparse' : 'urllib.parse',
+           'robotparser' : 'urllib.robotparser',
+}
+
+
+def alternates(members):
+    return "(" + "|".join(map(repr, members)) + ")"
+
+
+def build_pattern(mapping=MAPPING):
+    mod_list = ' | '.join(["module_name='%s'" % key for key in mapping])
+    bare_names = alternates(list(mapping.keys()))
+
+    yield """name_import=import_name< 'import' ((%s) |
+               multiple_imports=dotted_as_names< any* (%s) any* >) >
+          """ % (mod_list, mod_list)
+    yield """import_from< 'from' (%s) 'import' ['(']
+              ( any | import_as_name< any 'as' any > |
+                import_as_names< any* >)  [')'] >
+          """ % mod_list
+    yield """import_name< 'import' (dotted_as_name< (%s) 'as' any > |
+               multiple_imports=dotted_as_names<
+                 any* dotted_as_name< (%s) 'as' any > any* >) >
+          """ % (mod_list, mod_list)
+
+    # Find usages of module members in code e.g. thread.foo(bar)
+    yield "power< bare_with_attr=(%s) trailer<'.' any > any* >" % bare_names
+
+
+class FixImports(fixer_base.BaseFix):
+
+    BM_compatible = True
+    keep_line_order = True
+    # This is overridden in fix_imports2.
+    mapping = MAPPING
+
+    # We want to run this fixer late, so fix_import doesn't try to make stdlib
+    # renames into relative imports.
+    run_order = 6
+
+    def build_pattern(self):
+        return "|".join(build_pattern(self.mapping))
+
+    def compile_pattern(self):
+        # We override this, so MAPPING can be pragmatically altered and the
+        # changes will be reflected in PATTERN.
+        self.PATTERN = self.build_pattern()
+        super(FixImports, self).compile_pattern()
+
+    # Don't match the node if it's within another match.
+    def match(self, node):
+        match = super(FixImports, self).match
+        results = match(node)
+        if results:
+            # Module usage could be in the trailer of an attribute lookup, so we
+            # might have nested matches when "bare_with_attr" is present.
+            if "bare_with_attr" not in results and \
+                    any(match(obj) for obj in attr_chain(node, "parent")):
+                return False
+            return results
+        return False
+
+    def start_tree(self, tree, filename):
+        super(FixImports, self).start_tree(tree, filename)
+        self.replace = {}
+
+    def transform(self, node, results):
+        import_mod = results.get("module_name")
+        if import_mod:
+            mod_name = import_mod.value
+            new_name = str(self.mapping[mod_name])
+            import_mod.replace(Name(new_name, prefix=import_mod.prefix))
+            if "name_import" in results:
+                # If it's not a "from x import x, y" or "import x as y" import,
+                # marked its usage to be replaced.
+                self.replace[mod_name] = new_name
+            if "multiple_imports" in results:
+                # This is a nasty hack to fix multiple imports on a line (e.g.,
+                # "import StringIO, urlparse"). The problem is that I can't
+                # figure out an easy way to make a pattern recognize the keys of
+                # MAPPING randomly sprinkled in an import statement.
+                results = self.match(node)
+                if results:
+                    self.transform(node, results)
+        else:
+            # Replace usage of the module.
+            bare_name = results["bare_with_attr"][0]
+            new_name = self.replace.get(bare_name.value)
+            if new_name:
+                bare_name.replace(Name(new_name, prefix=bare_name.prefix))
diff --git a/lib3/2to3/lib2to3/fixes/fix_imports2.py b/lib3/2to3/lib2to3/fixes/fix_imports2.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_imports2.py
@@ -0,0 +1,16 @@
+"""Fix incompatible imports and module references that must be fixed after
+fix_imports."""
+from . import fix_imports
+
+
+MAPPING = {
+            'whichdb': 'dbm',
+            'anydbm': 'dbm',
+          }
+
+
+class FixImports2(fix_imports.FixImports):
+
+    run_order = 7
+
+    mapping = MAPPING
diff --git a/lib3/2to3/lib2to3/fixes/fix_input.py b/lib3/2to3/lib2to3/fixes/fix_input.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_input.py
@@ -0,0 +1,26 @@
+"""Fixer that changes input(...) into eval(input(...))."""
+# Author: Andre Roberge
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Call, Name
+from .. import patcomp
+
+
+context = patcomp.compile_pattern("power< 'eval' trailer< '(' any ')' > >")
+
+
+class FixInput(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+              power< 'input' args=trailer< '(' [any] ')' > >
+              """
+
+    def transform(self, node, results):
+        # If we're already wrapped in a eval() call, we're done.
+        if context.match(node.parent.parent):
+            return
+
+        new = node.clone()
+        new.prefix = ""
+        return Call(Name("eval"), [new], prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_intern.py b/lib3/2to3/lib2to3/fixes/fix_intern.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_intern.py
@@ -0,0 +1,46 @@
+# Copyright 2006 Georg Brandl.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for intern().
+
+intern(s) -> sys.intern(s)"""
+
+# Local imports
+from .. import pytree
+from .. import fixer_base
+from ..fixer_util import Name, Attr, touch_import
+
+
+class FixIntern(fixer_base.BaseFix):
+    BM_compatible = True
+    order = "pre"
+
+    PATTERN = """
+    power< 'intern'
+           trailer< lpar='('
+                    ( not(arglist | argument<any '=' any>) obj=any
+                      | obj=arglist<(not argument<any '=' any>) any ','> )
+                    rpar=')' >
+           after=any*
+    >
+    """
+
+    def transform(self, node, results):
+        syms = self.syms
+        obj = results["obj"].clone()
+        if obj.type == syms.arglist:
+            newarglist = obj.clone()
+        else:
+            newarglist = pytree.Node(syms.arglist, [obj.clone()])
+        after = results["after"]
+        if after:
+            after = [n.clone() for n in after]
+        new = pytree.Node(syms.power,
+                          Attr(Name("sys"), Name("intern")) +
+                          [pytree.Node(syms.trailer,
+                                       [results["lpar"].clone(),
+                                        newarglist,
+                                        results["rpar"].clone()])] + after)
+        new.prefix = node.prefix
+        touch_import(None, 'sys', node)
+        return new
diff --git a/lib3/2to3/lib2to3/fixes/fix_isinstance.py b/lib3/2to3/lib2to3/fixes/fix_isinstance.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_isinstance.py
@@ -0,0 +1,52 @@
+# Copyright 2008 Armin Ronacher.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that cleans up a tuple argument to isinstance after the tokens
+in it were fixed.  This is mainly used to remove double occurrences of
+tokens as a leftover of the long -> int / unicode -> str conversion.
+
+eg.  isinstance(x, (int, long)) -> isinstance(x, (int, int))
+       -> isinstance(x, int)
+"""
+
+from .. import fixer_base
+from ..fixer_util import token
+
+
+class FixIsinstance(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+    power<
+        'isinstance'
+        trailer< '(' arglist< any ',' atom< '('
+            args=testlist_gexp< any+ >
+        ')' > > ')' >
+    >
+    """
+
+    run_order = 6
+
+    def transform(self, node, results):
+        names_inserted = set()
+        testlist = results["args"]
+        args = testlist.children
+        new_args = []
+        iterator = enumerate(args)
+        for idx, arg in iterator:
+            if arg.type == token.NAME and arg.value in names_inserted:
+                if idx < len(args) - 1 and args[idx + 1].type == token.COMMA:
+                    next(iterator)
+                    continue
+            else:
+                new_args.append(arg)
+                if arg.type == token.NAME:
+                    names_inserted.add(arg.value)
+        if new_args and new_args[-1].type == token.COMMA:
+            del new_args[-1]
+        if len(new_args) == 1:
+            atom = testlist.parent
+            new_args[0].prefix = atom.prefix
+            atom.replace(new_args[0])
+        else:
+            args[:] = new_args
+            node.changed()
diff --git a/lib3/2to3/lib2to3/fixes/fix_itertools.py b/lib3/2to3/lib2to3/fixes/fix_itertools.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_itertools.py
@@ -0,0 +1,42 @@
+""" Fixer for itertools.(imap|ifilter|izip) --> (map|filter|zip) and
+    itertools.ifilterfalse --> itertools.filterfalse (bugs 2360-2363)
+
+    imports from itertools are fixed in fix_itertools_import.py
+
+    If itertools is imported as something else (ie: import itertools as it;
+    it.izip(spam, eggs)) method calls will not get fixed.
+    """
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+class FixItertools(fixer_base.BaseFix):
+    BM_compatible = True
+    it_funcs = "('imap'|'ifilter'|'izip'|'ifilterfalse')"
+    PATTERN = """
+              power< it='itertools'
+                  trailer<
+                     dot='.' func=%(it_funcs)s > trailer< '(' [any] ')' > >
+              |
+              power< func=%(it_funcs)s trailer< '(' [any] ')' > >
+              """ %(locals())
+
+    # Needs to be run after fix_(map|zip|filter)
+    run_order = 6
+
+    def transform(self, node, results):
+        prefix = None
+        func = results['func'][0]
+        if 'it' in results and func.value != 'ifilterfalse':
+            dot, it = (results['dot'], results['it'])
+            # Remove the 'itertools'
+            prefix = it.prefix
+            it.remove()
+            # Replace the node wich contains ('.', 'function') with the
+            # function (to be consistant with the second part of the pattern)
+            dot.remove()
+            func.parent.replace(func)
+
+        prefix = prefix or func.prefix
+        func.replace(Name(func.value[1:], prefix=prefix))
diff --git a/lib3/2to3/lib2to3/fixes/fix_itertools_imports.py b/lib3/2to3/lib2to3/fixes/fix_itertools_imports.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_itertools_imports.py
@@ -0,0 +1,56 @@
+""" Fixer for imports of itertools.(imap|ifilter|izip|ifilterfalse) """
+
+# Local imports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import BlankLine, syms, token
+
+
+class FixItertoolsImports(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+              import_from< 'from' 'itertools' 'import' imports=any >
+              """ %(locals())
+
+    def transform(self, node, results):
+        imports = results['imports']
+        if imports.type == syms.import_as_name or not imports.children:
+            children = [imports]
+        else:
+            children = imports.children
+        for child in children[::2]:
+            if child.type == token.NAME:
+                member = child.value
+                name_node = child
+            elif child.type == token.STAR:
+                # Just leave the import as is.
+                return
+            else:
+                assert child.type == syms.import_as_name
+                name_node = child.children[0]
+            member_name = name_node.value
+            if member_name in ('imap', 'izip', 'ifilter'):
+                child.value = None
+                child.remove()
+            elif member_name == 'ifilterfalse':
+                node.changed()
+                name_node.value = 'filterfalse'
+
+        # Make sure the import statement is still sane
+        children = imports.children[:] or [imports]
+        remove_comma = True
+        for child in children:
+            if remove_comma and child.type == token.COMMA:
+                child.remove()
+            else:
+                remove_comma ^= True
+
+        while children and children[-1].type == token.COMMA:
+            children.pop().remove()
+
+        # If there are no imports left, just get rid of the entire statement
+        if (not (imports.children or getattr(imports, 'value', None)) or
+            imports.parent is None):
+            p = node.prefix
+            node = BlankLine()
+            node.prefix = p
+            return node
diff --git a/lib3/2to3/lib2to3/fixes/fix_long.py b/lib3/2to3/lib2to3/fixes/fix_long.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_long.py
@@ -0,0 +1,19 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that turns 'long' into 'int' everywhere.
+"""
+
+# Local imports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import is_probably_builtin
+
+
+class FixLong(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = "'long'"
+
+    def transform(self, node, results):
+        if is_probably_builtin(node):
+            node.value = "int"
+            node.changed()
diff --git a/lib3/2to3/lib2to3/fixes/fix_map.py b/lib3/2to3/lib2to3/fixes/fix_map.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_map.py
@@ -0,0 +1,91 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that changes map(F, ...) into list(map(F, ...)) unless there
+exists a 'from future_builtins import map' statement in the top-level
+namespace.
+
+As a special case, map(None, X) is changed into list(X).  (This is
+necessary because the semantics are changed in this case -- the new
+map(None, X) is equivalent to [(x,) for x in X].)
+
+We avoid the transformation (except for the special case mentioned
+above) if the map() call is directly contained in iter(<>), list(<>),
+tuple(<>), sorted(<>), ...join(<>), or for V in <>:.
+
+NOTE: This is still not correct if the original code was depending on
+map(F, X, Y, ...) to go on until the longest argument is exhausted,
+substituting None for missing values -- like zip(), it now stops as
+soon as the shortest argument is exhausted.
+"""
+
+# Local imports
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, ListComp, in_special_context
+from ..pygram import python_symbols as syms
+
+class FixMap(fixer_base.ConditionalFix):
+    BM_compatible = True
+
+    PATTERN = """
+    map_none=power<
+        'map'
+        trailer< '(' arglist< 'None' ',' arg=any [','] > ')' >
+    >
+    |
+    map_lambda=power<
+        'map'
+        trailer<
+            '('
+            arglist<
+                lambdef< 'lambda'
+                         (fp=NAME | vfpdef< '(' fp=NAME ')'> ) ':' xp=any
+                >
+                ','
+                it=any
+            >
+            ')'
+        >
+    >
+    |
+    power<
+        'map' trailer< '(' [arglist=any] ')' >
+    >
+    """
+
+    skip_on = 'future_builtins.map'
+
+    def transform(self, node, results):
+        if self.should_skip(node):
+            return
+
+        if node.parent.type == syms.simple_stmt:
+            self.warning(node, "You should use a for loop here")
+            new = node.clone()
+            new.prefix = ""
+            new = Call(Name("list"), [new])
+        elif "map_lambda" in results:
+            new = ListComp(results["xp"].clone(),
+                           results["fp"].clone(),
+                           results["it"].clone())
+        else:
+            if "map_none" in results:
+                new = results["arg"].clone()
+            else:
+                if "arglist" in results:
+                    args = results["arglist"]
+                    if args.type == syms.arglist and \
+                       args.children[0].type == token.NAME and \
+                       args.children[0].value == "None":
+                        self.warning(node, "cannot convert map(None, ...) "
+                                     "with multiple arguments because map() "
+                                     "now truncates to the shortest sequence")
+                        return
+                if in_special_context(node):
+                    return None
+                new = node.clone()
+            new.prefix = ""
+            new = Call(Name("list"), [new])
+        new.prefix = node.prefix
+        return new
diff --git a/lib3/2to3/lib2to3/fixes/fix_metaclass.py b/lib3/2to3/lib2to3/fixes/fix_metaclass.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_metaclass.py
@@ -0,0 +1,228 @@
+"""Fixer for __metaclass__ = X -> (metaclass=X) methods.
+
+   The various forms of classef (inherits nothing, inherits once, inherints
+   many) don't parse the same in the CST so we look at ALL classes for
+   a __metaclass__ and if we find one normalize the inherits to all be
+   an arglist.
+
+   For one-liner classes ('class X: pass') there is no indent/dedent so
+   we normalize those into having a suite.
+
+   Moving the __metaclass__ into the classdef can also cause the class
+   body to be empty so there is some special casing for that as well.
+
+   This fixer also tries very hard to keep original indenting and spacing
+   in all those corner cases.
+
+"""
+# Author: Jack Diederich
+
+# Local imports
+from .. import fixer_base
+from ..pygram import token
+from ..fixer_util import Name, syms, Node, Leaf
+
+
+def has_metaclass(parent):
+    """ we have to check the cls_node without changing it.
+        There are two possiblities:
+          1)  clsdef => suite => simple_stmt => expr_stmt => Leaf('__meta')
+          2)  clsdef => simple_stmt => expr_stmt => Leaf('__meta')
+    """
+    for node in parent.children:
+        if node.type == syms.suite:
+            return has_metaclass(node)
+        elif node.type == syms.simple_stmt and node.children:
+            expr_node = node.children[0]
+            if expr_node.type == syms.expr_stmt and expr_node.children:
+                left_side = expr_node.children[0]
+                if isinstance(left_side, Leaf) and \
+                        left_side.value == '__metaclass__':
+                    return True
+    return False
+
+
+def fixup_parse_tree(cls_node):
+    """ one-line classes don't get a suite in the parse tree so we add
+        one to normalize the tree
+    """
+    for node in cls_node.children:
+        if node.type == syms.suite:
+            # already in the prefered format, do nothing
+            return
+
+    # !%@#! oneliners have no suite node, we have to fake one up
+    for i, node in enumerate(cls_node.children):
+        if node.type == token.COLON:
+            break
+    else:
+        raise ValueError("No class suite and no ':'!")
+
+    # move everything into a suite node
+    suite = Node(syms.suite, [])
+    while cls_node.children[i+1:]:
+        move_node = cls_node.children[i+1]
+        suite.append_child(move_node.clone())
+        move_node.remove()
+    cls_node.append_child(suite)
+    node = suite
+
+
+def fixup_simple_stmt(parent, i, stmt_node):
+    """ if there is a semi-colon all the parts count as part of the same
+        simple_stmt.  We just want the __metaclass__ part so we move
+        everything efter the semi-colon into its own simple_stmt node
+    """
+    for semi_ind, node in enumerate(stmt_node.children):
+        if node.type == token.SEMI: # *sigh*
+            break
+    else:
+        return
+
+    node.remove() # kill the semicolon
+    new_expr = Node(syms.expr_stmt, [])
+    new_stmt = Node(syms.simple_stmt, [new_expr])
+    while stmt_node.children[semi_ind:]:
+        move_node = stmt_node.children[semi_ind]
+        new_expr.append_child(move_node.clone())
+        move_node.remove()
+    parent.insert_child(i, new_stmt)
+    new_leaf1 = new_stmt.children[0].children[0]
+    old_leaf1 = stmt_node.children[0].children[0]
+    new_leaf1.prefix = old_leaf1.prefix
+
+
+def remove_trailing_newline(node):
+    if node.children and node.children[-1].type == token.NEWLINE:
+        node.children[-1].remove()
+
+
+def find_metas(cls_node):
+    # find the suite node (Mmm, sweet nodes)
+    for node in cls_node.children:
+        if node.type == syms.suite:
+            break
+    else:
+        raise ValueError("No class suite!")
+
+    # look for simple_stmt[ expr_stmt[ Leaf('__metaclass__') ] ]
+    for i, simple_node in list(enumerate(node.children)):
+        if simple_node.type == syms.simple_stmt and simple_node.children:
+            expr_node = simple_node.children[0]
+            if expr_node.type == syms.expr_stmt and expr_node.children:
+                # Check if the expr_node is a simple assignment.
+                left_node = expr_node.children[0]
+                if isinstance(left_node, Leaf) and \
+                        left_node.value == '__metaclass__':
+                    # We found a assignment to __metaclass__.
+                    fixup_simple_stmt(node, i, simple_node)
+                    remove_trailing_newline(simple_node)
+                    yield (node, i, simple_node)
+
+
+def fixup_indent(suite):
+    """ If an INDENT is followed by a thing with a prefix then nuke the prefix
+        Otherwise we get in trouble when removing __metaclass__ at suite start
+    """
+    kids = suite.children[::-1]
+    # find the first indent
+    while kids:
+        node = kids.pop()
+        if node.type == token.INDENT:
+            break
+
+    # find the first Leaf
+    while kids:
+        node = kids.pop()
+        if isinstance(node, Leaf) and node.type != token.DEDENT:
+            if node.prefix:
+                node.prefix = ''
+            return
+        else:
+            kids.extend(node.children[::-1])
+
+
+class FixMetaclass(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+    classdef<any*>
+    """
+
+    def transform(self, node, results):
+        if not has_metaclass(node):
+            return
+
+        fixup_parse_tree(node)
+
+        # find metaclasses, keep the last one
+        last_metaclass = None
+        for suite, i, stmt in find_metas(node):
+            last_metaclass = stmt
+            stmt.remove()
+
+        text_type = node.children[0].type # always Leaf(nnn, 'class')
+
+        # figure out what kind of classdef we have
+        if len(node.children) == 7:
+            # Node(classdef, ['class', 'name', '(', arglist, ')', ':', suite])
+            #                 0        1       2    3        4    5    6
+            if node.children[3].type == syms.arglist:
+                arglist = node.children[3]
+            # Node(classdef, ['class', 'name', '(', 'Parent', ')', ':', suite])
+            else:
+                parent = node.children[3].clone()
+                arglist = Node(syms.arglist, [parent])
+                node.set_child(3, arglist)
+        elif len(node.children) == 6:
+            # Node(classdef, ['class', 'name', '(',  ')', ':', suite])
+            #                 0        1       2     3    4    5
+            arglist = Node(syms.arglist, [])
+            node.insert_child(3, arglist)
+        elif len(node.children) == 4:
+            # Node(classdef, ['class', 'name', ':', suite])
+            #                 0        1       2    3
+            arglist = Node(syms.arglist, [])
+            node.insert_child(2, Leaf(token.RPAR, ')'))
+            node.insert_child(2, arglist)
+            node.insert_child(2, Leaf(token.LPAR, '('))
+        else:
+            raise ValueError("Unexpected class definition")
+
+        # now stick the metaclass in the arglist
+        meta_txt = last_metaclass.children[0].children[0]
+        meta_txt.value = 'metaclass'
+        orig_meta_prefix = meta_txt.prefix
+
+        if arglist.children:
+            arglist.append_child(Leaf(token.COMMA, ','))
+            meta_txt.prefix = ' '
+        else:
+            meta_txt.prefix = ''
+
+        # compact the expression "metaclass = Meta" -> "metaclass=Meta"
+        expr_stmt = last_metaclass.children[0]
+        assert expr_stmt.type == syms.expr_stmt
+        expr_stmt.children[1].prefix = ''
+        expr_stmt.children[2].prefix = ''
+
+        arglist.append_child(last_metaclass)
+
+        fixup_indent(suite)
+
+        # check for empty suite
+        if not suite.children:
+            # one-liner that was just __metaclass_
+            suite.remove()
+            pass_leaf = Leaf(text_type, 'pass')
+            pass_leaf.prefix = orig_meta_prefix
+            node.append_child(pass_leaf)
+            node.append_child(Leaf(token.NEWLINE, '\n'))
+
+        elif len(suite.children) > 1 and \
+                 (suite.children[-2].type == token.INDENT and
+                  suite.children[-1].type == token.DEDENT):
+            # there was only one line in the class body and it was __metaclass__
+            pass_leaf = Leaf(text_type, 'pass')
+            suite.insert_child(-1, pass_leaf)
+            suite.insert_child(-1, Leaf(token.NEWLINE, '\n'))
diff --git a/lib3/2to3/lib2to3/fixes/fix_methodattrs.py b/lib3/2to3/lib2to3/fixes/fix_methodattrs.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_methodattrs.py
@@ -0,0 +1,24 @@
+"""Fix bound method attributes (method.im_? -> method.__?__).
+"""
+# Author: Christian Heimes
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+MAP = {
+    "im_func" : "__func__",
+    "im_self" : "__self__",
+    "im_class" : "__self__.__class__"
+    }
+
+class FixMethodattrs(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+    power< any+ trailer< '.' attr=('im_func' | 'im_self' | 'im_class') > any* >
+    """
+
+    def transform(self, node, results):
+        attr = results["attr"][0]
+        new = str(MAP[attr.value])
+        attr.replace(Name(new, prefix=attr.prefix))
diff --git a/lib3/2to3/lib2to3/fixes/fix_ne.py b/lib3/2to3/lib2to3/fixes/fix_ne.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_ne.py
@@ -0,0 +1,23 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that turns <> into !=."""
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+
+
+class FixNe(fixer_base.BaseFix):
+    # This is so simple that we don't need the pattern compiler.
+
+    _accept_type = token.NOTEQUAL
+
+    def match(self, node):
+        # Override
+        return node.value == "<>"
+
+    def transform(self, node, results):
+        new = pytree.Leaf(token.NOTEQUAL, "!=", prefix=node.prefix)
+        return new
diff --git a/lib3/2to3/lib2to3/fixes/fix_next.py b/lib3/2to3/lib2to3/fixes/fix_next.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_next.py
@@ -0,0 +1,103 @@
+"""Fixer for it.next() -> next(it), per PEP 3114."""
+# Author: Collin Winter
+
+# Things that currently aren't covered:
+#   - listcomp "next" names aren't warned
+#   - "with" statement targets aren't checked
+
+# Local imports
+from ..pgen2 import token
+from ..pygram import python_symbols as syms
+from .. import fixer_base
+from ..fixer_util import Name, Call, find_binding
+
+bind_warning = "Calls to builtin next() possibly shadowed by global binding"
+
+
+class FixNext(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+    power< base=any+ trailer< '.' attr='next' > trailer< '(' ')' > >
+    |
+    power< head=any+ trailer< '.' attr='next' > not trailer< '(' ')' > >
+    |
+    classdef< 'class' any+ ':'
+              suite< any*
+                     funcdef< 'def'
+                              name='next'
+                              parameters< '(' NAME ')' > any+ >
+                     any* > >
+    |
+    global=global_stmt< 'global' any* 'next' any* >
+    """
+
+    order = "pre" # Pre-order tree traversal
+
+    def start_tree(self, tree, filename):
+        super(FixNext, self).start_tree(tree, filename)
+
+        n = find_binding('next', tree)
+        if n:
+            self.warning(n, bind_warning)
+            self.shadowed_next = True
+        else:
+            self.shadowed_next = False
+
+    def transform(self, node, results):
+        assert results
+
+        base = results.get("base")
+        attr = results.get("attr")
+        name = results.get("name")
+
+        if base:
+            if self.shadowed_next:
+                attr.replace(Name("__next__", prefix=attr.prefix))
+            else:
+                base = [n.clone() for n in base]
+                base[0].prefix = ""
+                node.replace(Call(Name("next", prefix=node.prefix), base))
+        elif name:
+            n = Name("__next__", prefix=name.prefix)
+            name.replace(n)
+        elif attr:
+            # We don't do this transformation if we're assigning to "x.next".
+            # Unfortunately, it doesn't seem possible to do this in PATTERN,
+            #  so it's being done here.
+            if is_assign_target(node):
+                head = results["head"]
+                if "".join([str(n) for n in head]).strip() == '__builtin__':
+                    self.warning(node, bind_warning)
+                return
+            attr.replace(Name("__next__"))
+        elif "global" in results:
+            self.warning(node, bind_warning)
+            self.shadowed_next = True
+
+
+### The following functions help test if node is part of an assignment
+###  target.
+
+def is_assign_target(node):
+    assign = find_assign(node)
+    if assign is None:
+        return False
+
+    for child in assign.children:
+        if child.type == token.EQUAL:
+            return False
+        elif is_subtree(child, node):
+            return True
+    return False
+
+def find_assign(node):
+    if node.type == syms.expr_stmt:
+        return node
+    if node.type == syms.simple_stmt or node.parent is None:
+        return None
+    return find_assign(node.parent)
+
+def is_subtree(root, node):
+    if root == node:
+        return True
+    return any(is_subtree(c, node) for c in root.children)
diff --git a/lib3/2to3/lib2to3/fixes/fix_nonzero.py b/lib3/2to3/lib2to3/fixes/fix_nonzero.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_nonzero.py
@@ -0,0 +1,21 @@
+"""Fixer for __nonzero__ -> __bool__ methods."""
+# Author: Collin Winter
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, syms
+
+class FixNonzero(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+    classdef< 'class' any+ ':'
+              suite< any*
+                     funcdef< 'def' name='__nonzero__'
+                              parameters< '(' NAME ')' > any+ >
+                     any* > >
+    """
+
+    def transform(self, node, results):
+        name = results["name"]
+        new = Name("__bool__", prefix=name.prefix)
+        name.replace(new)
diff --git a/lib3/2to3/lib2to3/fixes/fix_numliterals.py b/lib3/2to3/lib2to3/fixes/fix_numliterals.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_numliterals.py
@@ -0,0 +1,28 @@
+"""Fixer that turns 1L into 1, 0755 into 0o755.
+"""
+# Copyright 2007 Georg Brandl.
+# Licensed to PSF under a Contributor Agreement.
+
+# Local imports
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Number
+
+
+class FixNumliterals(fixer_base.BaseFix):
+    # This is so simple that we don't need the pattern compiler.
+
+    _accept_type = token.NUMBER
+
+    def match(self, node):
+        # Override
+        return (node.value.startswith("0") or node.value[-1] in "Ll")
+
+    def transform(self, node, results):
+        val = node.value
+        if val[-1] in 'Ll':
+            val = val[:-1]
+        elif val.startswith('0') and val.isdigit() and len(set(val)) > 1:
+            val = "0o" + val[1:]
+
+        return Number(val, prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_operator.py b/lib3/2to3/lib2to3/fixes/fix_operator.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_operator.py
@@ -0,0 +1,99 @@
+"""Fixer for operator functions.
+
+operator.isCallable(obj)       -> hasattr(obj, '__call__')
+operator.sequenceIncludes(obj) -> operator.contains(obj)
+operator.isSequenceType(obj)   -> isinstance(obj, collections.Sequence)
+operator.isMappingType(obj)    -> isinstance(obj, collections.Mapping)
+operator.isNumberType(obj)     -> isinstance(obj, numbers.Number)
+operator.repeat(obj, n)        -> operator.mul(obj, n)
+operator.irepeat(obj, n)       -> operator.imul(obj, n)
+"""
+
+# Local imports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import Call, Name, String, touch_import
+import collections
+
+
+def invocation(s):
+    def dec(f):
+        f.invocation = s
+        return f
+    return dec
+
+
+class FixOperator(fixer_base.BaseFix):
+    BM_compatible = True
+    order = "pre"
+
+    methods = """
+              method=('isCallable'|'sequenceIncludes'
+                     |'isSequenceType'|'isMappingType'|'isNumberType'
+                     |'repeat'|'irepeat')
+              """
+    obj = "'(' obj=any ')'"
+    PATTERN = """
+              power< module='operator'
+                trailer< '.' %(methods)s > trailer< %(obj)s > >
+              |
+              power< %(methods)s trailer< %(obj)s > >
+              """ % dict(methods=methods, obj=obj)
+
+    def transform(self, node, results):
+        method = self._check_method(node, results)
+        if method is not None:
+            return method(node, results)
+
+    @invocation("operator.contains(%s)")
+    def _sequenceIncludes(self, node, results):
+        return self._handle_rename(node, results, "contains")
+
+    @invocation("hasattr(%s, '__call__')")
+    def _isCallable(self, node, results):
+        obj = results["obj"]
+        args = [obj.clone(), String(", "), String("'__call__'")]
+        return Call(Name("hasattr"), args, prefix=node.prefix)
+
+    @invocation("operator.mul(%s)")
+    def _repeat(self, node, results):
+        return self._handle_rename(node, results, "mul")
+
+    @invocation("operator.imul(%s)")
+    def _irepeat(self, node, results):
+        return self._handle_rename(node, results, "imul")
+
+    @invocation("isinstance(%s, collections.Sequence)")
+    def _isSequenceType(self, node, results):
+        return self._handle_type2abc(node, results, "collections", "Sequence")
+
+    @invocation("isinstance(%s, collections.Mapping)")
+    def _isMappingType(self, node, results):
+        return self._handle_type2abc(node, results, "collections", "Mapping")
+
+    @invocation("isinstance(%s, numbers.Number)")
+    def _isNumberType(self, node, results):
+        return self._handle_type2abc(node, results, "numbers", "Number")
+
+    def _handle_rename(self, node, results, name):
+        method = results["method"][0]
+        method.value = name
+        method.changed()
+
+    def _handle_type2abc(self, node, results, module, abc):
+        touch_import(None, module, node)
+        obj = results["obj"]
+        args = [obj.clone(), String(", " + ".".join([module, abc]))]
+        return Call(Name("isinstance"), args, prefix=node.prefix)
+
+    def _check_method(self, node, results):
+        # Issue #15834: don't encode to ASCII as that breaks in translation to
+        # Python 3.
+        method = getattr(self, "_" + str(results["method"][0].value))
+        if isinstance(method, collections.Callable):
+            if "module" in results:
+                return method
+            else:
+                sub = (str(results["obj"]),)
+                invocation_str = str(method.invocation) % sub
+                self.warning(node, "You should use '%s' here." % invocation_str)
+        return None
diff --git a/lib3/2to3/lib2to3/fixes/fix_paren.py b/lib3/2to3/lib2to3/fixes/fix_paren.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_paren.py
@@ -0,0 +1,44 @@
+"""Fixer that addes parentheses where they are required
+
+This converts ``[x for x in 1, 2]`` to ``[x for x in (1, 2)]``."""
+
+# By Taek Joo Kim and Benjamin Peterson
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import LParen, RParen
+
+# XXX This doesn't support nested for loops like [x for x in 1, 2 for x in 1, 2]
+class FixParen(fixer_base.BaseFix):
+    BM_compatible = True
+
+    PATTERN = """
+        atom< ('[' | '(')
+            (listmaker< any
+                comp_for<
+                    'for' NAME 'in'
+                    target=testlist_safe< any (',' any)+ [',']
+                     >
+                    [any]
+                >
+            >
+            |
+            testlist_gexp< any
+                comp_for<
+                    'for' NAME 'in'
+                    target=testlist_safe< any (',' any)+ [',']
+                     >
+                    [any]
+                >
+            >)
+        (']' | ')') >
+    """
+
+    def transform(self, node, results):
+        target = results["target"]
+
+        lparen = LParen()
+        lparen.prefix = target.prefix
+        target.prefix = "" # Make it hug the parentheses
+        target.insert_child(0, lparen)
+        target.append_child(RParen())
diff --git a/lib3/2to3/lib2to3/fixes/fix_print.py b/lib3/2to3/lib2to3/fixes/fix_print.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_print.py
@@ -0,0 +1,87 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for print.
+
+Change:
+    'print'          into 'print()'
+    'print ...'      into 'print(...)'
+    'print ... ,'    into 'print(..., end=" ")'
+    'print >>x, ...' into 'print(..., file=x)'
+
+No changes are applied if print_function is imported from __future__
+
+"""
+
+# Local imports
+from .. import patcomp
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, Comma, String, is_tuple
+
+
+parend_expr = patcomp.compile_pattern(
+              """atom< '(' [atom|STRING|NAME] ')' >"""
+              )
+
+
+class FixPrint(fixer_base.BaseFix):
+
+    BM_compatible = True
+
+    PATTERN = """
+              simple_stmt< any* bare='print' any* > | print_stmt
+              """
+
+    def transform(self, node, results):
+        assert results
+
+        bare_print = results.get("bare")
+
+        if bare_print:
+            # Special-case print all by itself
+            bare_print.replace(Call(Name("print"), [],
+                               prefix=bare_print.prefix))
+            return
+        assert node.children[0] == Name("print")
+        args = node.children[1:]
+        if len(args) == 1 and parend_expr.match(args[0]):
+            # We don't want to keep sticking parens around an
+            # already-parenthesised expression.
+            return
+
+        sep = end = file = None
+        if args and args[-1] == Comma():
+            args = args[:-1]
+            end = " "
+        if args and args[0] == pytree.Leaf(token.RIGHTSHIFT, ">>"):
+            assert len(args) >= 2
+            file = args[1].clone()
+            args = args[3:] # Strip a possible comma after the file expression
+        # Now synthesize a print(args, sep=..., end=..., file=...) node.
+        l_args = [arg.clone() for arg in args]
+        if l_args:
+            l_args[0].prefix = ""
+        if sep is not None or end is not None or file is not None:
+            if sep is not None:
+                self.add_kwarg(l_args, "sep", String(repr(sep)))
+            if end is not None:
+                self.add_kwarg(l_args, "end", String(repr(end)))
+            if file is not None:
+                self.add_kwarg(l_args, "file", file)
+        n_stmt = Call(Name("print"), l_args)
+        n_stmt.prefix = node.prefix
+        return n_stmt
+
+    def add_kwarg(self, l_nodes, s_kwd, n_expr):
+        # XXX All this prefix-setting may lose comments (though rarely)
+        n_expr.prefix = ""
+        n_argument = pytree.Node(self.syms.argument,
+                                 (Name(s_kwd),
+                                  pytree.Leaf(token.EQUAL, "="),
+                                  n_expr))
+        if l_nodes:
+            l_nodes.append(Comma())
+            n_argument.prefix = " "
+        l_nodes.append(n_argument)
diff --git a/lib3/2to3/lib2to3/fixes/fix_raise.py b/lib3/2to3/lib2to3/fixes/fix_raise.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_raise.py
@@ -0,0 +1,90 @@
+"""Fixer for 'raise E, V, T'
+
+raise         -> raise
+raise E       -> raise E
+raise E, V    -> raise E(V)
+raise E, V, T -> raise E(V).with_traceback(T)
+raise E, None, T -> raise E.with_traceback(T)
+
+raise (((E, E'), E''), E'''), V -> raise E(V)
+raise "foo", V, T               -> warns about string exceptions
+
+
+CAVEATS:
+1) "raise E, V" will be incorrectly translated if V is an exception
+   instance. The correct Python 3 idiom is
+
+        raise E from V
+
+   but since we can't detect instance-hood by syntax alone and since
+   any client code would have to be changed as well, we don't automate
+   this.
+"""
+# Author: Collin Winter
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, Attr, ArgList, is_tuple
+
+class FixRaise(fixer_base.BaseFix):
+
+    BM_compatible = True
+    PATTERN = """
+    raise_stmt< 'raise' exc=any [',' val=any [',' tb=any]] >
+    """
+
+    def transform(self, node, results):
+        syms = self.syms
+
+        exc = results["exc"].clone()
+        if exc.type == token.STRING:
+            msg = "Python 3 does not support string exceptions"
+            self.cannot_convert(node, msg)
+            return
+
+        # Python 2 supports
+        #  raise ((((E1, E2), E3), E4), E5), V
+        # as a synonym for
+        #  raise E1, V
+        # Since Python 3 will not support this, we recurse down any tuple
+        # literals, always taking the first element.
+        if is_tuple(exc):
+            while is_tuple(exc):
+                # exc.children[1:-1] is the unparenthesized tuple
+                # exc.children[1].children[0] is the first element of the tuple
+                exc = exc.children[1].children[0].clone()
+            exc.prefix = " "
+
+        if "val" not in results:
+            # One-argument raise
+            new = pytree.Node(syms.raise_stmt, [Name("raise"), exc])
+            new.prefix = node.prefix
+            return new
+
+        val = results["val"].clone()
+        if is_tuple(val):
+            args = [c.clone() for c in val.children[1:-1]]
+        else:
+            val.prefix = ""
+            args = [val]
+
+        if "tb" in results:
+            tb = results["tb"].clone()
+            tb.prefix = ""
+
+            e = exc
+            # If there's a traceback and None is passed as the value, then don't
+            # add a call, since the user probably just wants to add a
+            # traceback. See issue #9661.
+            if val.type != token.NAME or val.value != "None":
+                e = Call(exc, args)
+            with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])]
+            new = pytree.Node(syms.simple_stmt, [Name("raise")] + with_tb)
+            new.prefix = node.prefix
+            return new
+        else:
+            return pytree.Node(syms.raise_stmt,
+                               [Name("raise"), Call(exc, args)],
+                               prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_raw_input.py b/lib3/2to3/lib2to3/fixes/fix_raw_input.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_raw_input.py
@@ -0,0 +1,17 @@
+"""Fixer that changes raw_input(...) into input(...)."""
+# Author: Andre Roberge
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+class FixRawInput(fixer_base.BaseFix):
+
+    BM_compatible = True
+    PATTERN = """
+              power< name='raw_input' trailer< '(' [any] ')' > any* >
+              """
+
+    def transform(self, node, results):
+        name = results["name"]
+        name.replace(Name("input", prefix=name.prefix))
diff --git a/lib3/2to3/lib2to3/fixes/fix_reduce.py b/lib3/2to3/lib2to3/fixes/fix_reduce.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_reduce.py
@@ -0,0 +1,35 @@
+# Copyright 2008 Armin Ronacher.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for reduce().
+
+Makes sure reduce() is imported from the functools module if reduce is
+used in that module.
+"""
+
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import touch_import
+
+
+
+class FixReduce(fixer_base.BaseFix):
+
+    BM_compatible = True
+    order = "pre"
+
+    PATTERN = """
+    power< 'reduce'
+        trailer< '('
+            arglist< (
+                (not(argument<any '=' any>) any ','
+                 not(argument<any '=' any>) any) |
+                (not(argument<any '=' any>) any ','
+                 not(argument<any '=' any>) any ','
+                 not(argument<any '=' any>) any)
+            ) >
+        ')' >
+    >
+    """
+
+    def transform(self, node, results):
+        touch_import('functools', 'reduce', node)
diff --git a/lib3/2to3/lib2to3/fixes/fix_renames.py b/lib3/2to3/lib2to3/fixes/fix_renames.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_renames.py
@@ -0,0 +1,70 @@
+"""Fix incompatible renames
+
+Fixes:
+  * sys.maxint -> sys.maxsize
+"""
+# Author: Christian Heimes
+# based on Collin Winter's fix_import
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, attr_chain
+
+MAPPING = {"sys":  {"maxint" : "maxsize"},
+          }
+LOOKUP = {}
+
+def alternates(members):
+    return "(" + "|".join(map(repr, members)) + ")"
+
+
+def build_pattern():
+    #bare = set()
+    for module, replace in list(MAPPING.items()):
+        for old_attr, new_attr in list(replace.items()):
+            LOOKUP[(module, old_attr)] = new_attr
+            #bare.add(module)
+            #bare.add(old_attr)
+            #yield """
+            #      import_name< 'import' (module=%r
+            #          | dotted_as_names< any* module=%r any* >) >
+            #      """ % (module, module)
+            yield """
+                  import_from< 'from' module_name=%r 'import'
+                      ( attr_name=%r | import_as_name< attr_name=%r 'as' any >) >
+                  """ % (module, old_attr, old_attr)
+            yield """
+                  power< module_name=%r trailer< '.' attr_name=%r > any* >
+                  """ % (module, old_attr)
+    #yield """bare_name=%s""" % alternates(bare)
+
+
+class FixRenames(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = "|".join(build_pattern())
+
+    order = "pre" # Pre-order tree traversal
+
+    # Don't match the node if it's within another match
+    def match(self, node):
+        match = super(FixRenames, self).match
+        results = match(node)
+        if results:
+            if any(match(obj) for obj in attr_chain(node, "parent")):
+                return False
+            return results
+        return False
+
+    #def start_tree(self, tree, filename):
+    #    super(FixRenames, self).start_tree(tree, filename)
+    #    self.replace = {}
+
+    def transform(self, node, results):
+        mod_name = results.get("module_name")
+        attr_name = results.get("attr_name")
+        #bare_name = results.get("bare_name")
+        #import_mod = results.get("module")
+
+        if mod_name and attr_name:
+            new_attr = str(LOOKUP[(mod_name.value, attr_name.value)])
+            attr_name.replace(Name(new_attr, prefix=attr_name.prefix))
diff --git a/lib3/2to3/lib2to3/fixes/fix_repr.py b/lib3/2to3/lib2to3/fixes/fix_repr.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_repr.py
@@ -0,0 +1,23 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that transforms `xyzzy` into repr(xyzzy)."""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Call, Name, parenthesize
+
+
+class FixRepr(fixer_base.BaseFix):
+
+    BM_compatible = True
+    PATTERN = """
+              atom < '`' expr=any '`' >
+              """
+
+    def transform(self, node, results):
+        expr = results["expr"].clone()
+
+        if expr.type == self.syms.testlist1:
+            expr = parenthesize(expr)
+        return Call(Name("repr"), [expr], prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_set_literal.py b/lib3/2to3/lib2to3/fixes/fix_set_literal.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_set_literal.py
@@ -0,0 +1,53 @@
+"""
+Optional fixer to transform set() calls to set literals.
+"""
+
+# Author: Benjamin Peterson
+
+from lib2to3 import fixer_base, pytree
+from lib2to3.fixer_util import token, syms
+
+
+
+class FixSetLiteral(fixer_base.BaseFix):
+
+    BM_compatible = True
+    explicit = True
+
+    PATTERN = """power< 'set' trailer< '('
+                     (atom=atom< '[' (items=listmaker< any ((',' any)* [',']) >
+                                |
+                                single=any) ']' >
+                     |
+                     atom< '(' items=testlist_gexp< any ((',' any)* [',']) > ')' >
+                     )
+                     ')' > >
+              """
+
+    def transform(self, node, results):
+        single = results.get("single")
+        if single:
+            # Make a fake listmaker
+            fake = pytree.Node(syms.listmaker, [single.clone()])
+            single.replace(fake)
+            items = fake
+        else:
+            items = results["items"]
+
+        # Build the contents of the literal
+        literal = [pytree.Leaf(token.LBRACE, "{")]
+        literal.extend(n.clone() for n in items.children)
+        literal.append(pytree.Leaf(token.RBRACE, "}"))
+        # Set the prefix of the right brace to that of the ')' or ']'
+        literal[-1].prefix = items.next_sibling.prefix
+        maker = pytree.Node(syms.dictsetmaker, literal)
+        maker.prefix = node.prefix
+
+        # If the original was a one tuple, we need to remove the extra comma.
+        if len(maker.children) == 4:
+            n = maker.children[2]
+            n.remove()
+            maker.children[-1].prefix = n.prefix
+
+        # Finally, replace the set call with our shiny new literal.
+        return maker
diff --git a/lib3/2to3/lib2to3/fixes/fix_standarderror.py b/lib3/2to3/lib2to3/fixes/fix_standarderror.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_standarderror.py
@@ -0,0 +1,18 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for StandardError -> Exception."""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+
+class FixStandarderror(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+              'StandardError'
+              """
+
+    def transform(self, node, results):
+        return Name("Exception", prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_sys_exc.py b/lib3/2to3/lib2to3/fixes/fix_sys_exc.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_sys_exc.py
@@ -0,0 +1,30 @@
+"""Fixer for sys.exc_{type, value, traceback}
+
+sys.exc_type -> sys.exc_info()[0]
+sys.exc_value -> sys.exc_info()[1]
+sys.exc_traceback -> sys.exc_info()[2]
+"""
+
+# By Jeff Balogh and Benjamin Peterson
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Attr, Call, Name, Number, Subscript, Node, syms
+
+class FixSysExc(fixer_base.BaseFix):
+    # This order matches the ordering of sys.exc_info().
+    exc_info = ["exc_type", "exc_value", "exc_traceback"]
+    BM_compatible = True
+    PATTERN = """
+              power< 'sys' trailer< dot='.' attribute=(%s) > >
+              """ % '|'.join("'%s'" % e for e in exc_info)
+
+    def transform(self, node, results):
+        sys_attr = results["attribute"][0]
+        index = Number(self.exc_info.index(sys_attr.value))
+
+        call = Call(Name("exc_info"), prefix=sys_attr.prefix)
+        attr = Attr(Name("sys"), call)
+        attr[1].children[0].prefix = results["dot"].prefix
+        attr.append(Subscript(index))
+        return Node(syms.power, attr, prefix=node.prefix)
diff --git a/lib3/2to3/lib2to3/fixes/fix_throw.py b/lib3/2to3/lib2to3/fixes/fix_throw.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_throw.py
@@ -0,0 +1,56 @@
+"""Fixer for generator.throw(E, V, T).
+
+g.throw(E)       -> g.throw(E)
+g.throw(E, V)    -> g.throw(E(V))
+g.throw(E, V, T) -> g.throw(E(V).with_traceback(T))
+
+g.throw("foo"[, V[, T]]) will warn about string exceptions."""
+# Author: Collin Winter
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name, Call, ArgList, Attr, is_tuple
+
+class FixThrow(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+    power< any trailer< '.' 'throw' >
+           trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' >
+    >
+    |
+    power< any trailer< '.' 'throw' > trailer< '(' exc=any ')' > >
+    """
+
+    def transform(self, node, results):
+        syms = self.syms
+
+        exc = results["exc"].clone()
+        if exc.type is token.STRING:
+            self.cannot_convert(node, "Python 3 does not support string exceptions")
+            return
+
+        # Leave "g.throw(E)" alone
+        val = results.get("val")
+        if val is None:
+            return
+
+        val = val.clone()
+        if is_tuple(val):
+            args = [c.clone() for c in val.children[1:-1]]
+        else:
+            val.prefix = ""
+            args = [val]
+
+        throw_args = results["args"]
+
+        if "tb" in results:
+            tb = results["tb"].clone()
+            tb.prefix = ""
+
+            e = Call(exc, args)
+            with_tb = Attr(e, Name('with_traceback')) + [ArgList([tb])]
+            throw_args.replace(pytree.Node(syms.power, with_tb))
+        else:
+            throw_args.replace(Call(exc, args))
diff --git a/lib3/2to3/lib2to3/fixes/fix_tuple_params.py b/lib3/2to3/lib2to3/fixes/fix_tuple_params.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_tuple_params.py
@@ -0,0 +1,175 @@
+"""Fixer for function definitions with tuple parameters.
+
+def func(((a, b), c), d):
+    ...
+
+    ->
+
+def func(x, d):
+    ((a, b), c) = x
+    ...
+
+It will also support lambdas:
+
+    lambda (x, y): x + y -> lambda t: t[0] + t[1]
+
+    # The parens are a syntax error in Python 3
+    lambda (x): x + y -> lambda x: x + y
+"""
+# Author: Collin Winter
+
+# Local imports
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Assign, Name, Newline, Number, Subscript, syms
+
+def is_docstring(stmt):
+    return isinstance(stmt, pytree.Node) and \
+           stmt.children[0].type == token.STRING
+
+class FixTupleParams(fixer_base.BaseFix):
+    run_order = 4 #use a lower order since lambda is part of other
+                  #patterns
+    BM_compatible = True
+
+    PATTERN = """
+              funcdef< 'def' any parameters< '(' args=any ')' >
+                       ['->' any] ':' suite=any+ >
+              |
+              lambda=
+              lambdef< 'lambda' args=vfpdef< '(' inner=any ')' >
+                       ':' body=any
+              >
+              """
+
+    def transform(self, node, results):
+        if "lambda" in results:
+            return self.transform_lambda(node, results)
+
+        new_lines = []
+        suite = results["suite"]
+        args = results["args"]
+        # This crap is so "def foo(...): x = 5; y = 7" is handled correctly.
+        # TODO(cwinter): suite-cleanup
+        if suite[0].children[1].type == token.INDENT:
+            start = 2
+            indent = suite[0].children[1].value
+            end = Newline()
+        else:
+            start = 0
+            indent = "; "
+            end = pytree.Leaf(token.INDENT, "")
+
+        # We need access to self for new_name(), and making this a method
+        #  doesn't feel right. Closing over self and new_lines makes the
+        #  code below cleaner.
+        def handle_tuple(tuple_arg, add_prefix=False):
+            n = Name(self.new_name())
+            arg = tuple_arg.clone()
+            arg.prefix = ""
+            stmt = Assign(arg, n.clone())
+            if add_prefix:
+                n.prefix = " "
+            tuple_arg.replace(n)
+            new_lines.append(pytree.Node(syms.simple_stmt,
+                                         [stmt, end.clone()]))
+
+        if args.type == syms.tfpdef:
+            handle_tuple(args)
+        elif args.type == syms.typedargslist:
+            for i, arg in enumerate(args.children):
+                if arg.type == syms.tfpdef:
+                    # Without add_prefix, the emitted code is correct,
+                    #  just ugly.
+                    handle_tuple(arg, add_prefix=(i > 0))
+
+        if not new_lines:
+            return
+
+        # This isn't strictly necessary, but it plays nicely with other fixers.
+        # TODO(cwinter) get rid of this when children becomes a smart list
+        for line in new_lines:
+            line.parent = suite[0]
+
+        # TODO(cwinter) suite-cleanup
+        after = start
+        if start == 0:
+            new_lines[0].prefix = " "
+        elif is_docstring(suite[0].children[start]):
+            new_lines[0].prefix = indent
+            after = start + 1
+
+        for line in new_lines:
+            line.parent = suite[0]
+        suite[0].children[after:after] = new_lines
+        for i in range(after+1, after+len(new_lines)+1):
+            suite[0].children[i].prefix = indent
+        suite[0].changed()
+
+    def transform_lambda(self, node, results):
+        args = results["args"]
+        body = results["body"]
+        inner = simplify_args(results["inner"])
+
+        # Replace lambda ((((x)))): x  with lambda x: x
+        if inner.type == token.NAME:
+            inner = inner.clone()
+            inner.prefix = " "
+            args.replace(inner)
+            return
+
+        params = find_params(args)
+        to_index = map_to_index(params)
+        tup_name = self.new_name(tuple_name(params))
+
+        new_param = Name(tup_name, prefix=" ")
+        args.replace(new_param.clone())
+        for n in body.post_order():
+            if n.type == token.NAME and n.value in to_index:
+                subscripts = [c.clone() for c in to_index[n.value]]
+                new = pytree.Node(syms.power,
+                                  [new_param.clone()] + subscripts)
+                new.prefix = n.prefix
+                n.replace(new)
+
+
+### Helper functions for transform_lambda()
+
+def simplify_args(node):
+    if node.type in (syms.vfplist, token.NAME):
+        return node
+    elif node.type == syms.vfpdef:
+        # These look like vfpdef< '(' x ')' > where x is NAME
+        # or another vfpdef instance (leading to recursion).
+        while node.type == syms.vfpdef:
+            node = node.children[1]
+        return node
+    raise RuntimeError("Received unexpected node %s" % node)
+
+def find_params(node):
+    if node.type == syms.vfpdef:
+        return find_params(node.children[1])
+    elif node.type == token.NAME:
+        return node.value
+    return [find_params(c) for c in node.children if c.type != token.COMMA]
+
+def map_to_index(param_list, prefix=[], d=None):
+    if d is None:
+        d = {}
+    for i, obj in enumerate(param_list):
+        trailer = [Subscript(Number(str(i)))]
+        if isinstance(obj, list):
+            map_to_index(obj, trailer, d=d)
+        else:
+            d[obj] = prefix + trailer
+    return d
+
+def tuple_name(param_list):
+    l = []
+    for obj in param_list:
+        if isinstance(obj, list):
+            l.append(tuple_name(obj))
+        else:
+            l.append(obj)
+    return "_".join(l)
diff --git a/lib3/2to3/lib2to3/fixes/fix_types.py b/lib3/2to3/lib2to3/fixes/fix_types.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_types.py
@@ -0,0 +1,62 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer for removing uses of the types module.
+
+These work for only the known names in the types module.  The forms above
+can include types. or not.  ie, It is assumed the module is imported either as:
+
+    import types
+    from types import ... # either * or specific types
+
+The import statements are not modified.
+
+There should be another fixer that handles at least the following constants:
+
+   type([]) -> list
+   type(()) -> tuple
+   type('') -> str
+
+"""
+
+# Local imports
+from ..pgen2 import token
+from .. import fixer_base
+from ..fixer_util import Name
+
+_TYPE_MAPPING = {
+        'BooleanType' : 'bool',
+        'BufferType' : 'memoryview',
+        'ClassType' : 'type',
+        'ComplexType' : 'complex',
+        'DictType': 'dict',
+        'DictionaryType' : 'dict',
+        'EllipsisType' : 'type(Ellipsis)',
+        #'FileType' : 'io.IOBase',
+        'FloatType': 'float',
+        'IntType': 'int',
+        'ListType': 'list',
+        'LongType': 'int',
+        'ObjectType' : 'object',
+        'NoneType': 'type(None)',
+        'NotImplementedType' : 'type(NotImplemented)',
+        'SliceType' : 'slice',
+        'StringType': 'bytes', # XXX ?
+        'StringTypes' : 'str', # XXX ?
+        'TupleType': 'tuple',
+        'TypeType' : 'type',
+        'UnicodeType': 'str',
+        'XRangeType' : 'range',
+    }
+
+_pats = ["power< 'types' trailer< '.' name='%s' > >" % t for t in _TYPE_MAPPING]
+
+class FixTypes(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = '|'.join(_pats)
+
+    def transform(self, node, results):
+        new_value = str(_TYPE_MAPPING.get(results["name"].value))
+        if new_value:
+            return Name(new_value, prefix=node.prefix)
+        return None
diff --git a/lib3/2to3/lib2to3/fixes/fix_unicode.py b/lib3/2to3/lib2to3/fixes/fix_unicode.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_unicode.py
@@ -0,0 +1,25 @@
+"""Fixer that changes unicode to str, unichr to chr, and u"..." into "...".
+
+"""
+
+import re
+from ..pgen2 import token
+from .. import fixer_base
+
+_mapping = {"unichr" : "chr", "unicode" : "str"}
+_literal_re = re.compile(r"[uU][rR]?[\'\"]")
+
+class FixUnicode(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = "STRING | 'unicode' | 'unichr'"
+
+    def transform(self, node, results):
+        if node.type == token.NAME:
+            new = node.clone()
+            new.value = _mapping[node.value]
+            return new
+        elif node.type == token.STRING:
+            if _literal_re.match(node.value):
+                new = node.clone()
+                new.value = new.value[1:]
+                return new
diff --git a/lib3/2to3/lib2to3/fixes/fix_urllib.py b/lib3/2to3/lib2to3/fixes/fix_urllib.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_urllib.py
@@ -0,0 +1,197 @@
+"""Fix changes imports of urllib which are now incompatible.
+   This is rather similar to fix_imports, but because of the more
+   complex nature of the fixing for urllib, it has its own fixer.
+"""
+# Author: Nick Edds
+
+# Local imports
+from lib2to3.fixes.fix_imports import alternates, FixImports
+from lib2to3 import fixer_base
+from lib2to3.fixer_util import (Name, Comma, FromImport, Newline,
+                                find_indentation, Node, syms)
+
+MAPPING = {"urllib":  [
+                ("urllib.request",
+                    ["URLopener", "FancyURLopener", "urlretrieve",
+                     "_urlopener", "urlopen", "urlcleanup",
+                     "pathname2url", "url2pathname"]),
+                ("urllib.parse",
+                    ["quote", "quote_plus", "unquote", "unquote_plus",
+                     "urlencode", "splitattr", "splithost", "splitnport",
+                     "splitpasswd", "splitport", "splitquery", "splittag",
+                     "splittype", "splituser", "splitvalue", ]),
+                ("urllib.error",
+                    ["ContentTooShortError"])],
+           "urllib2" : [
+                ("urllib.request",
+                    ["urlopen", "install_opener", "build_opener",
+                     "Request", "OpenerDirector", "BaseHandler",
+                     "HTTPDefaultErrorHandler", "HTTPRedirectHandler",
+                     "HTTPCookieProcessor", "ProxyHandler",
+                     "HTTPPasswordMgr",
+                     "HTTPPasswordMgrWithDefaultRealm",
+                     "AbstractBasicAuthHandler",
+                     "HTTPBasicAuthHandler", "ProxyBasicAuthHandler",
+                     "AbstractDigestAuthHandler",
+                     "HTTPDigestAuthHandler", "ProxyDigestAuthHandler",
+                     "HTTPHandler", "HTTPSHandler", "FileHandler",
+                     "FTPHandler", "CacheFTPHandler",
+                     "UnknownHandler"]),
+                ("urllib.error",
+                    ["URLError", "HTTPError"]),
+           ]
+}
+
+# Duplicate the url parsing functions for urllib2.
+MAPPING["urllib2"].append(MAPPING["urllib"][1])
+
+
+def build_pattern():
+    bare = set()
+    for old_module, changes in list(MAPPING.items()):
+        for change in changes:
+            new_module, members = change
+            members = alternates(members)
+            yield """import_name< 'import' (module=%r
+                                  | dotted_as_names< any* module=%r any* >) >
+                  """ % (old_module, old_module)
+            yield """import_from< 'from' mod_member=%r 'import'
+                       ( member=%s | import_as_name< member=%s 'as' any > |
+                         import_as_names< members=any*  >) >
+                  """ % (old_module, members, members)
+            yield """import_from< 'from' module_star=%r 'import' star='*' >
+                  """ % old_module
+            yield """import_name< 'import'
+                                  dotted_as_name< module_as=%r 'as' any > >
+                  """ % old_module
+            # bare_with_attr has a special significance for FixImports.match().
+            yield """power< bare_with_attr=%r trailer< '.' member=%s > any* >
+                  """ % (old_module, members)
+
+
+class FixUrllib(FixImports):
+
+    def build_pattern(self):
+        return "|".join(build_pattern())
+
+    def transform_import(self, node, results):
+        """Transform for the basic import case. Replaces the old
+           import name with a comma separated list of its
+           replacements.
+        """
+        import_mod = results.get("module")
+        pref = import_mod.prefix
+
+        names = []
+
+        # create a Node list of the replacement modules
+        for name in MAPPING[import_mod.value][:-1]:
+            names.extend([Name(name[0], prefix=pref), Comma()])
+        names.append(Name(MAPPING[import_mod.value][-1][0], prefix=pref))
+        import_mod.replace(names)
+
+    def transform_member(self, node, results):
+        """Transform for imports of specific module elements. Replaces
+           the module to be imported from with the appropriate new
+           module.
+        """
+        mod_member = results.get("mod_member")
+        pref = mod_member.prefix
+        member = results.get("member")
+
+        # Simple case with only a single member being imported
+        if member:
+            # this may be a list of length one, or just a node
+            if isinstance(member, list):
+                member = member[0]
+            new_name = None
+            for change in MAPPING[mod_member.value]:
+                if member.value in change[1]:
+                    new_name = change[0]
+                    break
+            if new_name:
+                mod_member.replace(Name(new_name, prefix=pref))
+            else:
+                self.cannot_convert(node, "This is an invalid module element")
+
+        # Multiple members being imported
+        else:
+            # a dictionary for replacements, order matters
+            modules = []
+            mod_dict = {}
+            members = results["members"]
+            for member in members:
+                # we only care about the actual members
+                if member.type == syms.import_as_name:
+                    as_name = member.children[2].value
+                    member_name = member.children[0].value
+                else:
+                    member_name = member.value
+                    as_name = None
+                if member_name != ",":
+                    for change in MAPPING[mod_member.value]:
+                        if member_name in change[1]:
+                            if change[0] not in mod_dict:
+                                modules.append(change[0])
+                            mod_dict.setdefault(change[0], []).append(member)
+
+            new_nodes = []
+            indentation = find_indentation(node)
+            first = True
+            def handle_name(name, prefix):
+                if name.type == syms.import_as_name:
+                    kids = [Name(name.children[0].value, prefix=prefix),
+                            name.children[1].clone(),
+                            name.children[2].clone()]
+                    return [Node(syms.import_as_name, kids)]
+                return [Name(name.value, prefix=prefix)]
+            for module in modules:
+                elts = mod_dict[module]
+                names = []
+                for elt in elts[:-1]:
+                    names.extend(handle_name(elt, pref))
+                    names.append(Comma())
+                names.extend(handle_name(elts[-1], pref))
+                new = FromImport(module, names)
+                if not first or node.parent.prefix.endswith(indentation):
+                    new.prefix = indentation
+                new_nodes.append(new)
+                first = False
+            if new_nodes:
+                nodes = []
+                for new_node in new_nodes[:-1]:
+                    nodes.extend([new_node, Newline()])
+                nodes.append(new_nodes[-1])
+                node.replace(nodes)
+            else:
+                self.cannot_convert(node, "All module elements are invalid")
+
+    def transform_dot(self, node, results):
+        """Transform for calls to module members in code."""
+        module_dot = results.get("bare_with_attr")
+        member = results.get("member")
+        new_name = None
+        if isinstance(member, list):
+            member = member[0]
+        for change in MAPPING[module_dot.value]:
+            if member.value in change[1]:
+                new_name = change[0]
+                break
+        if new_name:
+            module_dot.replace(Name(new_name,
+                                    prefix=module_dot.prefix))
+        else:
+            self.cannot_convert(node, "This is an invalid module element")
+
+    def transform(self, node, results):
+        if results.get("module"):
+            self.transform_import(node, results)
+        elif results.get("mod_member"):
+            self.transform_member(node, results)
+        elif results.get("bare_with_attr"):
+            self.transform_dot(node, results)
+        # Renaming and star imports are not supported for these modules.
+        elif results.get("module_star"):
+            self.cannot_convert(node, "Cannot handle star imports.")
+        elif results.get("module_as"):
+            self.cannot_convert(node, "This module is now multiple modules")
diff --git a/lib3/2to3/lib2to3/fixes/fix_ws_comma.py b/lib3/2to3/lib2to3/fixes/fix_ws_comma.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_ws_comma.py
@@ -0,0 +1,39 @@
+"""Fixer that changes 'a ,b' into 'a, b'.
+
+This also changes '{a :b}' into '{a: b}', but does not touch other
+uses of colons.  It does not touch other uses of whitespace.
+
+"""
+
+from .. import pytree
+from ..pgen2 import token
+from .. import fixer_base
+
+class FixWsComma(fixer_base.BaseFix):
+
+    explicit = True # The user must ask for this fixers
+
+    PATTERN = """
+    any<(not(',') any)+ ',' ((not(',') any)+ ',')* [not(',') any]>
+    """
+
+    COMMA = pytree.Leaf(token.COMMA, ",")
+    COLON = pytree.Leaf(token.COLON, ":")
+    SEPS = (COMMA, COLON)
+
+    def transform(self, node, results):
+        new = node.clone()
+        comma = False
+        for child in new.children:
+            if child in self.SEPS:
+                prefix = child.prefix
+                if prefix.isspace() and "\n" not in prefix:
+                    child.prefix = ""
+                comma = True
+            else:
+                if comma:
+                    prefix = child.prefix
+                    if not prefix:
+                        child.prefix = " "
+                comma = False
+        return new
diff --git a/lib3/2to3/lib2to3/fixes/fix_xrange.py b/lib3/2to3/lib2to3/fixes/fix_xrange.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_xrange.py
@@ -0,0 +1,73 @@
+# Copyright 2007 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Fixer that changes xrange(...) into range(...)."""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, Call, consuming_calls
+from .. import patcomp
+
+
+class FixXrange(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+              power<
+                 (name='range'|name='xrange') trailer< '(' args=any ')' >
+              rest=any* >
+              """
+
+    def start_tree(self, tree, filename):
+        super(FixXrange, self).start_tree(tree, filename)
+        self.transformed_xranges = set()
+
+    def finish_tree(self, tree, filename):
+        self.transformed_xranges = None
+
+    def transform(self, node, results):
+        name = results["name"]
+        if name.value == "xrange":
+            return self.transform_xrange(node, results)
+        elif name.value == "range":
+            return self.transform_range(node, results)
+        else:
+            raise ValueError(repr(name))
+
+    def transform_xrange(self, node, results):
+        name = results["name"]
+        name.replace(Name("range", prefix=name.prefix))
+        # This prevents the new range call from being wrapped in a list later.
+        self.transformed_xranges.add(id(node))
+
+    def transform_range(self, node, results):
+        if (id(node) not in self.transformed_xranges and
+            not self.in_special_context(node)):
+            range_call = Call(Name("range"), [results["args"].clone()])
+            # Encase the range call in list().
+            list_call = Call(Name("list"), [range_call],
+                             prefix=node.prefix)
+            # Put things that were after the range() call after the list call.
+            for n in results["rest"]:
+                list_call.append_child(n)
+            return list_call
+
+    P1 = "power< func=NAME trailer< '(' node=any ')' > any* >"
+    p1 = patcomp.compile_pattern(P1)
+
+    P2 = """for_stmt< 'for' any 'in' node=any ':' any* >
+            | comp_for< 'for' any 'in' node=any any* >
+            | comparison< any 'in' node=any any*>
+         """
+    p2 = patcomp.compile_pattern(P2)
+
+    def in_special_context(self, node):
+        if node.parent is None:
+            return False
+        results = {}
+        if (node.parent.parent is not None and
+               self.p1.match(node.parent.parent, results) and
+               results["node"] is node):
+            # list(d.keys()) -> list(d.keys()), etc.
+            return results["func"].value in consuming_calls
+        # for ... in d.iterkeys() -> for ... in d.keys(), etc.
+        return self.p2.match(node.parent, results) and results["node"] is node
diff --git a/lib3/2to3/lib2to3/fixes/fix_xreadlines.py b/lib3/2to3/lib2to3/fixes/fix_xreadlines.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_xreadlines.py
@@ -0,0 +1,25 @@
+"""Fix "for x in f.xreadlines()" -> "for x in f".
+
+This fixer will also convert g(f.xreadlines) into g(f.__iter__)."""
+# Author: Collin Winter
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name
+
+
+class FixXreadlines(fixer_base.BaseFix):
+    BM_compatible = True
+    PATTERN = """
+    power< call=any+ trailer< '.' 'xreadlines' > trailer< '(' ')' > >
+    |
+    power< any+ trailer< '.' no_call='xreadlines' > >
+    """
+
+    def transform(self, node, results):
+        no_call = results.get("no_call")
+
+        if no_call:
+            no_call.replace(Name("__iter__", prefix=no_call.prefix))
+        else:
+            node.replace([x.clone() for x in results["call"]])
diff --git a/lib3/2to3/lib2to3/fixes/fix_zip.py b/lib3/2to3/lib2to3/fixes/fix_zip.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/fixes/fix_zip.py
@@ -0,0 +1,35 @@
+"""
+Fixer that changes zip(seq0, seq1, ...) into list(zip(seq0, seq1, ...)
+unless there exists a 'from future_builtins import zip' statement in the
+top-level namespace.
+
+We avoid the transformation if the zip() call is directly contained in
+iter(<>), list(<>), tuple(<>), sorted(<>), ...join(<>), or for V in <>:.
+"""
+
+# Local imports
+from .. import fixer_base
+from ..fixer_util import Name, Call, in_special_context
+
+class FixZip(fixer_base.ConditionalFix):
+
+    BM_compatible = True
+    PATTERN = """
+    power< 'zip' args=trailer< '(' [any] ')' >
+    >
+    """
+
+    skip_on = "future_builtins.zip"
+
+    def transform(self, node, results):
+        if self.should_skip(node):
+            return
+
+        if in_special_context(node):
+            return None
+
+        new = node.clone()
+        new.prefix = ""
+        new = Call(Name("list"), [new])
+        new.prefix = node.prefix
+        return new
diff --git a/lib3/2to3/lib2to3/main.py b/lib3/2to3/lib2to3/main.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/main.py
@@ -0,0 +1,182 @@
+"""
+Main program for 2to3.
+"""
+
+
+
+import sys
+import os
+import difflib
+import logging
+import shutil
+import optparse
+
+from . import refactor
+
+
+def diff_texts(a, b, filename):
+    """Return a unified diff of two strings."""
+    a = a.splitlines()
+    b = b.splitlines()
+    return difflib.unified_diff(a, b, filename, filename,
+                                "(original)", "(refactored)",
+                                lineterm="")
+
+
+class StdoutRefactoringTool(refactor.MultiprocessRefactoringTool):
+    """
+    Prints output to stdout.
+    """
+
+    def __init__(self, fixers, options, explicit, nobackups, show_diffs):
+        self.nobackups = nobackups
+        self.show_diffs = show_diffs
+        super(StdoutRefactoringTool, self).__init__(fixers, options, explicit)
+
+    def log_error(self, msg, *args, **kwargs):
+        self.errors.append((msg, args, kwargs))
+        self.logger.error(msg, *args, **kwargs)
+
+    def write_file(self, new_text, filename, old_text, encoding):
+        if not self.nobackups:
+            # Make backup
+            backup = filename + ".bak"
+            if os.path.lexists(backup):
+                try:
+                    os.remove(backup)
+                except os.error as err:
+                    self.log_message("Can't remove backup %s", backup)
+            try:
+                os.rename(filename, backup)
+            except os.error as err:
+                self.log_message("Can't rename %s to %s", filename, backup)
+        # Actually write the new file
+        write = super(StdoutRefactoringTool, self).write_file
+        write(new_text, filename, old_text, encoding)
+        if not self.nobackups:
+            shutil.copymode(backup, filename)
+
+    def print_output(self, old, new, filename, equal):
+        if equal:
+            self.log_message("No changes to %s", filename)
+        else:
+            self.log_message("Refactored %s", filename)
+            if self.show_diffs:
+                diff_lines = diff_texts(old, new, filename)
+                try:
+                    if self.output_lock is not None:
+                        with self.output_lock:
+                            for line in diff_lines:
+                                print(line)
+                            sys.stdout.flush()
+                    else:
+                        for line in diff_lines:
+                            print(line)
+                except UnicodeEncodeError:
+                    warn("couldn't encode %s's diff for your terminal" %
+                         (filename,))
+                    return
+
+
+def warn(msg):
+    print("WARNING: %s" % (msg,), file=sys.stderr)
+
+
+def main(fixer_pkg, args=None):
+    """Main program.
+
+    Args:
+        fixer_pkg: the name of a package where the fixers are located.
+        args: optional; a list of command line arguments. If omitted,
+              sys.argv[1:] is used.
+
+    Returns a suggested exit status (0, 1, 2).
+    """
+    # Set up option parser
+    parser = optparse.OptionParser(usage="2to3 [options] file|dir ...")
+    parser.add_option("-d", "--doctests_only", action="store_true",
+                      help="Fix up doctests only")
+    parser.add_option("-f", "--fix", action="append", default=[],
+                      help="Each FIX specifies a transformation; default: all")
+    parser.add_option("-j", "--processes", action="store", default=1,
+                      type="int", help="Run 2to3 concurrently")
+    parser.add_option("-x", "--nofix", action="append", default=[],
+                      help="Prevent a transformation from being run")
+    parser.add_option("-l", "--list-fixes", action="store_true",
+                      help="List available transformations")
+    parser.add_option("-p", "--print-function", action="store_true",
+                      help="Modify the grammar so that print() is a function")
+    parser.add_option("-v", "--verbose", action="store_true",
+                      help="More verbose logging")
+    parser.add_option("--no-diffs", action="store_true",
+                      help="Don't show diffs of the refactoring")
+    parser.add_option("-w", "--write", action="store_true",
+                      help="Write back modified files")
+    parser.add_option("-n", "--nobackups", action="store_true", default=False,
+                      help="Don't write backups for modified files")
+
+    # Parse command line arguments
+    refactor_stdin = False
+    flags = {}
+    options, args = parser.parse_args(args)
+    if not options.write and options.no_diffs:
+        warn("not writing files and not printing diffs; that's not very useful")
+    if not options.write and options.nobackups:
+        parser.error("Can't use -n without -w")
+    if options.list_fixes:
+        print("Available transformations for the -f/--fix option:")
+        for fixname in refactor.get_all_fix_names(fixer_pkg):
+            print(fixname)
+        if not args:
+            return 0
+    if not args:
+        print("At least one file or directory argument required.", file=sys.stderr)
+        print("Use --help to show usage.", file=sys.stderr)
+        return 2
+    if "-" in args:
+        refactor_stdin = True
+        if options.write:
+            print("Can't write to stdin.", file=sys.stderr)
+            return 2
+    if options.print_function:
+        flags["print_function"] = True
+
+    # Set up logging handler
+    level = logging.DEBUG if options.verbose else logging.INFO
+    logging.basicConfig(format='%(name)s: %(message)s', level=level)
+
+    # Initialize the refactoring tool
+    avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg))
+    unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix)
+    explicit = set()
+    if options.fix:
+        all_present = False
+        for fix in options.fix:
+            if fix == "all":
+                all_present = True
+            else:
+                explicit.add(fixer_pkg + ".fix_" + fix)
+        requested = avail_fixes.union(explicit) if all_present else explicit
+    else:
+        requested = avail_fixes.union(explicit)
+    fixer_names = requested.difference(unwanted_fixes)
+    rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit),
+                               options.nobackups, not options.no_diffs)
+
+    # Refactor all files and directories passed as arguments
+    if not rt.errors:
+        if refactor_stdin:
+            rt.refactor_stdin()
+        else:
+            try:
+                rt.refactor(args, options.write, options.doctests_only,
+                            options.processes)
+            except refactor.MultiprocessingUnsupported:
+                assert options.processes > 1
+                print("Sorry, -j isn't " \
+                    "supported on this platform.", file=sys.stderr)
+                return 1
+        rt.summarize()
+
+    # Return error status (0 if rt.errors is zero)
+    return int(bool(rt.errors))
diff --git a/lib3/2to3/lib2to3/patcomp.py b/lib3/2to3/lib2to3/patcomp.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/patcomp.py
@@ -0,0 +1,204 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Pattern compiler.
+
+The grammer is taken from PatternGrammar.txt.
+
+The compiler compiles a pattern to a pytree.*Pattern instance.
+"""
+
+__author__ = "Guido van Rossum <guido at python.org>"
+
+# Python imports
+import os
+
+# Fairly local imports
+from .pgen2 import driver, literals, token, tokenize, parse, grammar
+
+# Really local imports
+from . import pytree
+from . import pygram
+
+# The pattern grammar file
+_PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__),
+                                     "PatternGrammar.txt")
+
+
+class PatternSyntaxError(Exception):
+    pass
+
+
+def tokenize_wrapper(input):
+    """Tokenizes a string suppressing significant whitespace."""
+    skip = set((token.NEWLINE, token.INDENT, token.DEDENT))
+    tokens = tokenize.generate_tokens(driver.generate_lines(input).__next__)
+    for quintuple in tokens:
+        type, value, start, end, line_text = quintuple
+        if type not in skip:
+            yield quintuple
+
+
+class PatternCompiler(object):
+
+    def __init__(self, grammar_file=_PATTERN_GRAMMAR_FILE):
+        """Initializer.
+
+        Takes an optional alternative filename for the pattern grammar.
+        """
+        self.grammar = driver.load_grammar(grammar_file)
+        self.syms = pygram.Symbols(self.grammar)
+        self.pygrammar = pygram.python_grammar
+        self.pysyms = pygram.python_symbols
+        self.driver = driver.Driver(self.grammar, convert=pattern_convert)
+
+    def compile_pattern(self, input, debug=False, with_tree=False):
+        """Compiles a pattern string to a nested pytree.*Pattern object."""
+        tokens = tokenize_wrapper(input)
+        try:
+            root = self.driver.parse_tokens(tokens, debug=debug)
+        except parse.ParseError as e:
+            raise PatternSyntaxError(str(e))
+        if with_tree:
+            return self.compile_node(root), root
+        else:
+            return self.compile_node(root)
+
+    def compile_node(self, node):
+        """Compiles a node, recursively.
+
+        This is one big switch on the node type.
+        """
+        # XXX Optimize certain Wildcard-containing-Wildcard patterns
+        # that can be merged
+        if node.type == self.syms.Matcher:
+            node = node.children[0] # Avoid unneeded recursion
+
+        if node.type == self.syms.Alternatives:
+            # Skip the odd children since they are just '|' tokens
+            alts = [self.compile_node(ch) for ch in node.children[::2]]
+            if len(alts) == 1:
+                return alts[0]
+            p = pytree.WildcardPattern([[a] for a in alts], min=1, max=1)
+            return p.optimize()
+
+        if node.type == self.syms.Alternative:
+            units = [self.compile_node(ch) for ch in node.children]
+            if len(units) == 1:
+                return units[0]
+            p = pytree.WildcardPattern([units], min=1, max=1)
+            return p.optimize()
+
+        if node.type == self.syms.NegatedUnit:
+            pattern = self.compile_basic(node.children[1:])
+            p = pytree.NegatedPattern(pattern)
+            return p.optimize()
+
+        assert node.type == self.syms.Unit
+
+        name = None
+        nodes = node.children
+        if len(nodes) >= 3 and nodes[1].type == token.EQUAL:
+            name = nodes[0].value
+            nodes = nodes[2:]
+        repeat = None
+        if len(nodes) >= 2 and nodes[-1].type == self.syms.Repeater:
+            repeat = nodes[-1]
+            nodes = nodes[:-1]
+
+        # Now we've reduced it to: STRING | NAME [Details] | (...) | [...]
+        pattern = self.compile_basic(nodes, repeat)
+
+        if repeat is not None:
+            assert repeat.type == self.syms.Repeater
+            children = repeat.children
+            child = children[0]
+            if child.type == token.STAR:
+                min = 0
+                max = pytree.HUGE
+            elif child.type == token.PLUS:
+                min = 1
+                max = pytree.HUGE
+            elif child.type == token.LBRACE:
+                assert children[-1].type == token.RBRACE
+                assert  len(children) in (3, 5)
+                min = max = self.get_int(children[1])
+                if len(children) == 5:
+                    max = self.get_int(children[3])
+            else:
+                assert False
+            if min != 1 or max != 1:
+                pattern = pattern.optimize()
+                pattern = pytree.WildcardPattern([[pattern]], min=min, max=max)
+
+        if name is not None:
+            pattern.name = name
+        return pattern.optimize()
+
+    def compile_basic(self, nodes, repeat=None):
+        # Compile STRING | NAME [Details] | (...) | [...]
+        assert len(nodes) >= 1
+        node = nodes[0]
+        if node.type == token.STRING:
+            value = str(literals.evalString(node.value))
+            return pytree.LeafPattern(_type_of_literal(value), value)
+        elif node.type == token.NAME:
+            value = node.value
+            if value.isupper():
+                if value not in TOKEN_MAP:
+                    raise PatternSyntaxError("Invalid token: %r" % value)
+                if nodes[1:]:
+                    raise PatternSyntaxError("Can't have details for token")
+                return pytree.LeafPattern(TOKEN_MAP[value])
+            else:
+                if value == "any":
+                    type = None
+                elif not value.startswith("_"):
+                    type = getattr(self.pysyms, value, None)
+                    if type is None:
+                        raise PatternSyntaxError("Invalid symbol: %r" % value)
+                if nodes[1:]: # Details present
+                    content = [self.compile_node(nodes[1].children[1])]
+                else:
+                    content = None
+                return pytree.NodePattern(type, content)
+        elif node.value == "(":
+            return self.compile_node(nodes[1])
+        elif node.value == "[":
+            assert repeat is None
+            subpattern = self.compile_node(nodes[1])
+            return pytree.WildcardPattern([[subpattern]], min=0, max=1)
+        assert False, node
+
+    def get_int(self, node):
+        assert node.type == token.NUMBER
+        return int(node.value)
+
+
+# Map named tokens to the type value for a LeafPattern
+TOKEN_MAP = {"NAME": token.NAME,
+             "STRING": token.STRING,
+             "NUMBER": token.NUMBER,
+             "TOKEN": None}
+
+
+def _type_of_literal(value):
+    if value[0].isalpha():
+        return token.NAME
+    elif value in grammar.opmap:
+        return grammar.opmap[value]
+    else:
+        return None
+
+
+def pattern_convert(grammar, raw_node_info):
+    """Converts raw node information to a Node or Leaf instance."""
+    type, value, context, children = raw_node_info
+    if children or type in grammar.number2symbol:
+        return pytree.Node(type, children, context=context)
+    else:
+        return pytree.Leaf(type, value, context=context)
+
+
+def compile_pattern(pattern):
+    return PatternCompiler().compile_pattern(pattern)
diff --git a/lib3/2to3/lib2to3/pgen2/__init__.py b/lib3/2to3/lib2to3/pgen2/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pgen2/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""The pgen2 package."""
diff --git a/lib3/2to3/lib2to3/pgen2/conv.py b/lib3/2to3/lib2to3/pgen2/conv.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pgen2/conv.py
@@ -0,0 +1,257 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Convert graminit.[ch] spit out by pgen to Python code.
+
+Pgen is the Python parser generator.  It is useful to quickly create a
+parser from a grammar file in Python's grammar notation.  But I don't
+want my parsers to be written in C (yet), so I'm translating the
+parsing tables to Python data structures and writing a Python parse
+engine.
+
+Note that the token numbers are constants determined by the standard
+Python tokenizer.  The standard token module defines these numbers and
+their names (the names are not used much).  The token numbers are
+hardcoded into the Python tokenizer and into pgen.  A Python
+implementation of the Python tokenizer is also available, in the
+standard tokenize module.
+
+On the other hand, symbol numbers (representing the grammar's
+non-terminals) are assigned by pgen based on the actual grammar
+input.
+
+Note: this module is pretty much obsolete; the pgen module generates
+equivalent grammar tables directly from the Grammar.txt input file
+without having to invoke the Python pgen C program.
+
+"""
+
+# Python imports
+import re
+
+# Local imports
+from pgen2 import grammar, token
+
+
+class Converter(grammar.Grammar):
+    """Grammar subclass that reads classic pgen output files.
+
+    The run() method reads the tables as produced by the pgen parser
+    generator, typically contained in two C files, graminit.h and
+    graminit.c.  The other methods are for internal use only.
+
+    See the base class for more documentation.
+
+    """
+
+    def run(self, graminit_h, graminit_c):
+        """Load the grammar tables from the text files written by pgen."""
+        self.parse_graminit_h(graminit_h)
+        self.parse_graminit_c(graminit_c)
+        self.finish_off()
+
+    def parse_graminit_h(self, filename):
+        """Parse the .h file writen by pgen.  (Internal)
+
+        This file is a sequence of #define statements defining the
+        nonterminals of the grammar as numbers.  We build two tables
+        mapping the numbers to names and back.
+
+        """
+        try:
+            f = open(filename)
+        except IOError as err:
+            print("Can't open %s: %s" % (filename, err))
+            return False
+        self.symbol2number = {}
+        self.number2symbol = {}
+        lineno = 0
+        for line in f:
+            lineno += 1
+            mo = re.match(r"^#define\s+(\w+)\s+(\d+)$", line)
+            if not mo and line.strip():
+                print("%s(%s): can't parse %s" % (filename, lineno,
+                                                  line.strip()))
+            else:
+                symbol, number = mo.groups()
+                number = int(number)
+                assert symbol not in self.symbol2number
+                assert number not in self.number2symbol
+                self.symbol2number[symbol] = number
+                self.number2symbol[number] = symbol
+        return True
+
+    def parse_graminit_c(self, filename):
+        """Parse the .c file writen by pgen.  (Internal)
+
+        The file looks as follows.  The first two lines are always this:
+
+        #include "pgenheaders.h"
+        #include "grammar.h"
+
+        After that come four blocks:
+
+        1) one or more state definitions
+        2) a table defining dfas
+        3) a table defining labels
+        4) a struct defining the grammar
+
+        A state definition has the following form:
+        - one or more arc arrays, each of the form:
+          static arc arcs_<n>_<m>[<k>] = {
+                  {<i>, <j>},
+                  ...
+          };
+        - followed by a state array, of the form:
+          static state states_<s>[<t>] = {
+                  {<k>, arcs_<n>_<m>},
+                  ...
+          };
+
+        """
+        try:
+            f = open(filename)
+        except IOError as err:
+            print("Can't open %s: %s" % (filename, err))
+            return False
+        # The code below essentially uses f's iterator-ness!
+        lineno = 0
+
+        # Expect the two #include lines
+        lineno, line = lineno+1, next(f)
+        assert line == '#include "pgenheaders.h"\n', (lineno, line)
+        lineno, line = lineno+1, next(f)
+        assert line == '#include "grammar.h"\n', (lineno, line)
+
+        # Parse the state definitions
+        lineno, line = lineno+1, next(f)
+        allarcs = {}
+        states = []
+        while line.startswith("static arc "):
+            while line.startswith("static arc "):
+                mo = re.match(r"static arc arcs_(\d+)_(\d+)\[(\d+)\] = {$",
+                              line)
+                assert mo, (lineno, line)
+                n, m, k = list(map(int, mo.groups()))
+                arcs = []
+                for _ in range(k):
+                    lineno, line = lineno+1, next(f)
+                    mo = re.match(r"\s+{(\d+), (\d+)},$", line)
+                    assert mo, (lineno, line)
+                    i, j = list(map(int, mo.groups()))
+                    arcs.append((i, j))
+                lineno, line = lineno+1, next(f)
+                assert line == "};\n", (lineno, line)
+                allarcs[(n, m)] = arcs
+                lineno, line = lineno+1, next(f)
+            mo = re.match(r"static state states_(\d+)\[(\d+)\] = {$", line)
+            assert mo, (lineno, line)
+            s, t = list(map(int, mo.groups()))
+            assert s == len(states), (lineno, line)
+            state = []
+            for _ in range(t):
+                lineno, line = lineno+1, next(f)
+                mo = re.match(r"\s+{(\d+), arcs_(\d+)_(\d+)},$", line)
+                assert mo, (lineno, line)
+                k, n, m = list(map(int, mo.groups()))
+                arcs = allarcs[n, m]
+                assert k == len(arcs), (lineno, line)
+                state.append(arcs)
+            states.append(state)
+            lineno, line = lineno+1, next(f)
+            assert line == "};\n", (lineno, line)
+            lineno, line = lineno+1, next(f)
+        self.states = states
+
+        # Parse the dfas
+        dfas = {}
+        mo = re.match(r"static dfa dfas\[(\d+)\] = {$", line)
+        assert mo, (lineno, line)
+        ndfas = int(mo.group(1))
+        for i in range(ndfas):
+            lineno, line = lineno+1, next(f)
+            mo = re.match(r'\s+{(\d+), "(\w+)", (\d+), (\d+), states_(\d+),$',
+                          line)
+            assert mo, (lineno, line)
+            symbol = mo.group(2)
+            number, x, y, z = list(map(int, mo.group(1, 3, 4, 5)))
+            assert self.symbol2number[symbol] == number, (lineno, line)
+            assert self.number2symbol[number] == symbol, (lineno, line)
+            assert x == 0, (lineno, line)
+            state = states[z]
+            assert y == len(state), (lineno, line)
+            lineno, line = lineno+1, next(f)
+            mo = re.match(r'\s+("(?:\\\d\d\d)*")},$', line)
+            assert mo, (lineno, line)
+            first = {}
+            rawbitset = eval(mo.group(1))
+            for i, c in enumerate(rawbitset):
+                byte = ord(c)
+                for j in range(8):
+                    if byte & (1<<j):
+                        first[i*8 + j] = 1
+            dfas[number] = (state, first)
+        lineno, line = lineno+1, next(f)
+        assert line == "};\n", (lineno, line)
+        self.dfas = dfas
+
+        # Parse the labels
+        labels = []
+        lineno, line = lineno+1, next(f)
+        mo = re.match(r"static label labels\[(\d+)\] = {$", line)
+        assert mo, (lineno, line)
+        nlabels = int(mo.group(1))
+        for i in range(nlabels):
+            lineno, line = lineno+1, next(f)
+            mo = re.match(r'\s+{(\d+), (0|"\w+")},$', line)
+            assert mo, (lineno, line)
+            x, y = mo.groups()
+            x = int(x)
+            if y == "0":
+                y = None
+            else:
+                y = eval(y)
+            labels.append((x, y))
+        lineno, line = lineno+1, next(f)
+        assert line == "};\n", (lineno, line)
+        self.labels = labels
+
+        # Parse the grammar struct
+        lineno, line = lineno+1, next(f)
+        assert line == "grammar _PyParser_Grammar = {\n", (lineno, line)
+        lineno, line = lineno+1, next(f)
+        mo = re.match(r"\s+(\d+),$", line)
+        assert mo, (lineno, line)
+        ndfas = int(mo.group(1))
+        assert ndfas == len(self.dfas)
+        lineno, line = lineno+1, next(f)
+        assert line == "\tdfas,\n", (lineno, line)
+        lineno, line = lineno+1, next(f)
+        mo = re.match(r"\s+{(\d+), labels},$", line)
+        assert mo, (lineno, line)
+        nlabels = int(mo.group(1))
+        assert nlabels == len(self.labels), (lineno, line)
+        lineno, line = lineno+1, next(f)
+        mo = re.match(r"\s+(\d+)$", line)
+        assert mo, (lineno, line)
+        start = int(mo.group(1))
+        assert start in self.number2symbol, (lineno, line)
+        self.start = start
+        lineno, line = lineno+1, next(f)
+        assert line == "};\n", (lineno, line)
+        try:
+            lineno, line = lineno+1, next(f)
+        except StopIteration:
+            pass
+        else:
+            assert 0, (lineno, line)
+
+    def finish_off(self):
+        """Create additional useful structures.  (Internal)."""
+        self.keywords = {} # map from keyword strings to arc labels
+        self.tokens = {}   # map from numeric token values to arc labels
+        for ilabel, (type, value) in enumerate(self.labels):
+            if type == token.NAME and value is not None:
+                self.keywords[value] = ilabel
+            elif value is None:
+                self.tokens[type] = ilabel
diff --git a/lib3/2to3/lib2to3/pgen2/driver.py b/lib3/2to3/lib2to3/pgen2/driver.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pgen2/driver.py
@@ -0,0 +1,147 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# Modifications:
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Parser driver.
+
+This provides a high-level interface to parse a file into a syntax tree.
+
+"""
+
+__author__ = "Guido van Rossum <guido at python.org>"
+
+__all__ = ["Driver", "load_grammar"]
+
+# Python imports
+import codecs
+import os
+import logging
+import sys
+
+# Pgen imports
+from . import grammar, parse, token, tokenize, pgen
+
+
+class Driver(object):
+
+    def __init__(self, grammar, convert=None, logger=None):
+        self.grammar = grammar
+        if logger is None:
+            logger = logging.getLogger()
+        self.logger = logger
+        self.convert = convert
+
+    def parse_tokens(self, tokens, debug=False):
+        """Parse a series of tokens and return the syntax tree."""
+        # XXX Move the prefix computation into a wrapper around tokenize.
+        p = parse.Parser(self.grammar, self.convert)
+        p.setup()
+        lineno = 1
+        column = 0
+        type = value = start = end = line_text = None
+        prefix = ""
+        for quintuple in tokens:
+            type, value, start, end, line_text = quintuple
+            if start != (lineno, column):
+                assert (lineno, column) <= start, ((lineno, column), start)
+                s_lineno, s_column = start
+                if lineno < s_lineno:
+                    prefix += "\n" * (s_lineno - lineno)
+                    lineno = s_lineno
+                    column = 0
+                if column < s_column:
+                    prefix += line_text[column:s_column]
+                    column = s_column
+            if type in (tokenize.COMMENT, tokenize.NL):
+                prefix += value
+                lineno, column = end
+                if value.endswith("\n"):
+                    lineno += 1
+                    column = 0
+                continue
+            if type == token.OP:
+                type = grammar.opmap[value]
+            if debug:
+                self.logger.debug("%s %r (prefix=%r)",
+                                  token.tok_name[type], value, prefix)
+            if p.addtoken(type, value, (prefix, start)):
+                if debug:
+                    self.logger.debug("Stop.")
+                break
+            prefix = ""
+            lineno, column = end
+            if value.endswith("\n"):
+                lineno += 1
+                column = 0
+        else:
+            # We never broke out -- EOF is too soon (how can this happen???)
+            raise parse.ParseError("incomplete input",
+                                   type, value, (prefix, start))
+        return p.rootnode
+
+    def parse_stream_raw(self, stream, debug=False):
+        """Parse a stream and return the syntax tree."""
+        tokens = tokenize.generate_tokens(stream.readline)
+        return self.parse_tokens(tokens, debug)
+
+    def parse_stream(self, stream, debug=False):
+        """Parse a stream and return the syntax tree."""
+        return self.parse_stream_raw(stream, debug)
+
+    def parse_file(self, filename, encoding=None, debug=False):
+        """Parse a file and return the syntax tree."""
+        stream = codecs.open(filename, "r", encoding)
+        try:
+            return self.parse_stream(stream, debug)
+        finally:
+            stream.close()
+
+    def parse_string(self, text, debug=False):
+        """Parse a string and return the syntax tree."""
+        tokens = tokenize.generate_tokens(generate_lines(text).__next__)
+        return self.parse_tokens(tokens, debug)
+
+
+def generate_lines(text):
+    """Generator that behaves like readline without using StringIO."""
+    for line in text.splitlines(True):
+        yield line
+    while True:
+        yield ""
+
+
+def load_grammar(gt="Grammar.txt", gp=None,
+                 save=True, force=False, logger=None):
+    """Load the grammar (maybe from a pickle)."""
+    if logger is None:
+        logger = logging.getLogger()
+    if gp is None:
+        head, tail = os.path.splitext(gt)
+        if tail == ".txt":
+            tail = ""
+        gp = head + tail + ".".join(map(str, sys.version_info)) + ".pickle"
+    if force or not _newer(gp, gt):
+        logger.info("Generating grammar tables from %s", gt)
+        g = pgen.generate_grammar(gt)
+        if save:
+            logger.info("Writing grammar tables to %s", gp)
+            try:
+                g.dump(gp)
+            except IOError as e:
+                logger.info("Writing failed:"+str(e))
+    else:
+        g = grammar.Grammar()
+        g.load(gp)
+    return g
+
+
+def _newer(a, b):
+    """Inquire whether file a was written since file b."""
+    if not os.path.exists(a):
+        return False
+    if not os.path.exists(b):
+        return True
+    return os.path.getmtime(a) >= os.path.getmtime(b)
diff --git a/lib3/2to3/lib2to3/pgen2/grammar.py b/lib3/2to3/lib2to3/pgen2/grammar.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pgen2/grammar.py
@@ -0,0 +1,184 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""This module defines the data structures used to represent a grammar.
+
+These are a bit arcane because they are derived from the data
+structures used by Python's 'pgen' parser generator.
+
+There's also a table here mapping operators to their names in the
+token module; the Python tokenize module reports all operators as the
+fallback token code OP, but the parser needs the actual token code.
+
+"""
+
+# Python imports
+import pickle
+
+# Local imports
+from . import token, tokenize
+
+
+class Grammar(object):
+    """Pgen parsing tables tables conversion class.
+
+    Once initialized, this class supplies the grammar tables for the
+    parsing engine implemented by parse.py.  The parsing engine
+    accesses the instance variables directly.  The class here does not
+    provide initialization of the tables; several subclasses exist to
+    do this (see the conv and pgen modules).
+
+    The load() method reads the tables from a pickle file, which is
+    much faster than the other ways offered by subclasses.  The pickle
+    file is written by calling dump() (after loading the grammar
+    tables using a subclass).  The report() method prints a readable
+    representation of the tables to stdout, for debugging.
+
+    The instance variables are as follows:
+
+    symbol2number -- a dict mapping symbol names to numbers.  Symbol
+                     numbers are always 256 or higher, to distinguish
+                     them from token numbers, which are between 0 and
+                     255 (inclusive).
+
+    number2symbol -- a dict mapping numbers to symbol names;
+                     these two are each other's inverse.
+
+    states        -- a list of DFAs, where each DFA is a list of
+                     states, each state is is a list of arcs, and each
+                     arc is a (i, j) pair where i is a label and j is
+                     a state number.  The DFA number is the index into
+                     this list.  (This name is slightly confusing.)
+                     Final states are represented by a special arc of
+                     the form (0, j) where j is its own state number.
+
+    dfas          -- a dict mapping symbol numbers to (DFA, first)
+                     pairs, where DFA is an item from the states list
+                     above, and first is a set of tokens that can
+                     begin this grammar rule (represented by a dict
+                     whose values are always 1).
+
+    labels        -- a list of (x, y) pairs where x is either a token
+                     number or a symbol number, and y is either None
+                     or a string; the strings are keywords.  The label
+                     number is the index in this list; label numbers
+                     are used to mark state transitions (arcs) in the
+                     DFAs.
+
+    start         -- the number of the grammar's start symbol.
+
+    keywords      -- a dict mapping keyword strings to arc labels.
+
+    tokens        -- a dict mapping token numbers to arc labels.
+
+    """
+
+    def __init__(self):
+        self.symbol2number = {}
+        self.number2symbol = {}
+        self.states = []
+        self.dfas = {}
+        self.labels = [(0, "EMPTY")]
+        self.keywords = {}
+        self.tokens = {}
+        self.symbol2label = {}
+        self.start = 256
+
+    def dump(self, filename):
+        """Dump the grammar tables to a pickle file."""
+        f = open(filename, "wb")
+        pickle.dump(self.__dict__, f, 2)
+        f.close()
+
+    def load(self, filename):
+        """Load the grammar tables from a pickle file."""
+        f = open(filename, "rb")
+        d = pickle.load(f)
+        f.close()
+        self.__dict__.update(d)
+
+    def copy(self):
+        """
+        Copy the grammar.
+        """
+        new = self.__class__()
+        for dict_attr in ("symbol2number", "number2symbol", "dfas", "keywords",
+                          "tokens", "symbol2label"):
+            setattr(new, dict_attr, getattr(self, dict_attr).copy())
+        new.labels = self.labels[:]
+        new.states = self.states[:]
+        new.start = self.start
+        return new
+
+    def report(self):
+        """Dump the grammar tables to standard output, for debugging."""
+        from pprint import pprint
+        print("s2n")
+        pprint(self.symbol2number)
+        print("n2s")
+        pprint(self.number2symbol)
+        print("states")
+        pprint(self.states)
+        print("dfas")
+        pprint(self.dfas)
+        print("labels")
+        pprint(self.labels)
+        print("start", self.start)
+
+
+# Map from operator to number (since tokenize doesn't do this)
+
+opmap_raw = """
+( LPAR
+) RPAR
+[ LSQB
+] RSQB
+: COLON
+, COMMA
+; SEMI
++ PLUS
+- MINUS
+* STAR
+/ SLASH
+| VBAR
+& AMPER
+< LESS
+> GREATER
+= EQUAL
+. DOT
+% PERCENT
+` BACKQUOTE
+{ LBRACE
+} RBRACE
+@ AT
+== EQEQUAL
+!= NOTEQUAL
+<> NOTEQUAL
+<= LESSEQUAL
+>= GREATEREQUAL
+~ TILDE
+^ CIRCUMFLEX
+<< LEFTSHIFT
+>> RIGHTSHIFT
+** DOUBLESTAR
++= PLUSEQUAL
+-= MINEQUAL
+*= STAREQUAL
+/= SLASHEQUAL
+%= PERCENTEQUAL
+&= AMPEREQUAL
+|= VBAREQUAL
+^= CIRCUMFLEXEQUAL
+<<= LEFTSHIFTEQUAL
+>>= RIGHTSHIFTEQUAL
+**= DOUBLESTAREQUAL
+// DOUBLESLASH
+//= DOUBLESLASHEQUAL
+-> RARROW
+"""
+
+opmap = {}
+for line in opmap_raw.splitlines():
+    if line:
+        op, name = line.split()
+        opmap[op] = getattr(token, name)
diff --git a/lib3/2to3/lib2to3/pgen2/literals.py b/lib3/2to3/lib2to3/pgen2/literals.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pgen2/literals.py
@@ -0,0 +1,60 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Safely evaluate Python string literals without using eval()."""
+
+import re
+
+simple_escapes = {"a": "\a",
+                  "b": "\b",
+                  "f": "\f",
+                  "n": "\n",
+                  "r": "\r",
+                  "t": "\t",
+                  "v": "\v",
+                  "'": "'",
+                  '"': '"',
+                  "\\": "\\"}
+
+def escape(m):
+    all, tail = m.group(0, 1)
+    assert all.startswith("\\")
+    esc = simple_escapes.get(tail)
+    if esc is not None:
+        return esc
+    if tail.startswith("x"):
+        hexes = tail[1:]
+        if len(hexes) < 2:
+            raise ValueError("invalid hex string escape ('\\%s')" % tail)
+        try:
+            i = int(hexes, 16)
+        except ValueError:
+            raise ValueError("invalid hex string escape ('\\%s')" % tail)
+    else:
+        try:
+            i = int(tail, 8)
+        except ValueError:
+            raise ValueError("invalid octal string escape ('\\%s')" % tail)
+    return chr(i)
+
+def evalString(s):
+    assert s.startswith("'") or s.startswith('"'), repr(s[:1])
+    q = s[0]
+    if s[:3] == q*3:
+        q = q*3
+    assert s.endswith(q), repr(s[-len(q):])
+    assert len(s) >= 2*len(q)
+    s = s[len(q):-len(q)]
+    return re.sub(r"\\(\'|\"|\\|[abfnrtv]|x.{0,2}|[0-7]{1,3})", escape, s)
+
+def test():
+    for i in range(256):
+        c = chr(i)
+        s = repr(c)
+        e = evalString(s)
+        if e != c:
+            print(i, c, s, e)
+
+
+if __name__ == "__main__":
+    test()
diff --git a/lib3/2to3/lib2to3/pgen2/parse.py b/lib3/2to3/lib2to3/pgen2/parse.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pgen2/parse.py
@@ -0,0 +1,201 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Parser engine for the grammar tables generated by pgen.
+
+The grammar table must be loaded first.
+
+See Parser/parser.c in the Python distribution for additional info on
+how this parsing engine works.
+
+"""
+
+# Local imports
+from . import token
+
+class ParseError(Exception):
+    """Exception to signal the parser is stuck."""
+
+    def __init__(self, msg, type, value, context):
+        Exception.__init__(self, "%s: type=%r, value=%r, context=%r" %
+                           (msg, type, value, context))
+        self.msg = msg
+        self.type = type
+        self.value = value
+        self.context = context
+
+class Parser(object):
+    """Parser engine.
+
+    The proper usage sequence is:
+
+    p = Parser(grammar, [converter])  # create instance
+    p.setup([start])                  # prepare for parsing
+    <for each input token>:
+        if p.addtoken(...):           # parse a token; may raise ParseError
+            break
+    root = p.rootnode                 # root of abstract syntax tree
+
+    A Parser instance may be reused by calling setup() repeatedly.
+
+    A Parser instance contains state pertaining to the current token
+    sequence, and should not be used concurrently by different threads
+    to parse separate token sequences.
+
+    See driver.py for how to get input tokens by tokenizing a file or
+    string.
+
+    Parsing is complete when addtoken() returns True; the root of the
+    abstract syntax tree can then be retrieved from the rootnode
+    instance variable.  When a syntax error occurs, addtoken() raises
+    the ParseError exception.  There is no error recovery; the parser
+    cannot be used after a syntax error was reported (but it can be
+    reinitialized by calling setup()).
+
+    """
+
+    def __init__(self, grammar, convert=None):
+        """Constructor.
+
+        The grammar argument is a grammar.Grammar instance; see the
+        grammar module for more information.
+
+        The parser is not ready yet for parsing; you must call the
+        setup() method to get it started.
+
+        The optional convert argument is a function mapping concrete
+        syntax tree nodes to abstract syntax tree nodes.  If not
+        given, no conversion is done and the syntax tree produced is
+        the concrete syntax tree.  If given, it must be a function of
+        two arguments, the first being the grammar (a grammar.Grammar
+        instance), and the second being the concrete syntax tree node
+        to be converted.  The syntax tree is converted from the bottom
+        up.
+
+        A concrete syntax tree node is a (type, value, context, nodes)
+        tuple, where type is the node type (a token or symbol number),
+        value is None for symbols and a string for tokens, context is
+        None or an opaque value used for error reporting (typically a
+        (lineno, offset) pair), and nodes is a list of children for
+        symbols, and None for tokens.
+
+        An abstract syntax tree node may be anything; this is entirely
+        up to the converter function.
+
+        """
+        self.grammar = grammar
+        self.convert = convert or (lambda grammar, node: node)
+
+    def setup(self, start=None):
+        """Prepare for parsing.
+
+        This *must* be called before starting to parse.
+
+        The optional argument is an alternative start symbol; it
+        defaults to the grammar's start symbol.
+
+        You can use a Parser instance to parse any number of programs;
+        each time you call setup() the parser is reset to an initial
+        state determined by the (implicit or explicit) start symbol.
+
+        """
+        if start is None:
+            start = self.grammar.start
+        # Each stack entry is a tuple: (dfa, state, node).
+        # A node is a tuple: (type, value, context, children),
+        # where children is a list of nodes or None, and context may be None.
+        newnode = (start, None, None, [])
+        stackentry = (self.grammar.dfas[start], 0, newnode)
+        self.stack = [stackentry]
+        self.rootnode = None
+        self.used_names = set() # Aliased to self.rootnode.used_names in pop()
+
+    def addtoken(self, type, value, context):
+        """Add a token; return True iff this is the end of the program."""
+        # Map from token to label
+        ilabel = self.classify(type, value, context)
+        # Loop until the token is shifted; may raise exceptions
+        while True:
+            dfa, state, node = self.stack[-1]
+            states, first = dfa
+            arcs = states[state]
+            # Look for a state with this label
+            for i, newstate in arcs:
+                t, v = self.grammar.labels[i]
+                if ilabel == i:
+                    # Look it up in the list of labels
+                    assert t < 256
+                    # Shift a token; we're done with it
+                    self.shift(type, value, newstate, context)
+                    # Pop while we are in an accept-only state
+                    state = newstate
+                    while states[state] == [(0, state)]:
+                        self.pop()
+                        if not self.stack:
+                            # Done parsing!
+                            return True
+                        dfa, state, node = self.stack[-1]
+                        states, first = dfa
+                    # Done with this token
+                    return False
+                elif t >= 256:
+                    # See if it's a symbol and if we're in its first set
+                    itsdfa = self.grammar.dfas[t]
+                    itsstates, itsfirst = itsdfa
+                    if ilabel in itsfirst:
+                        # Push a symbol
+                        self.push(t, self.grammar.dfas[t], newstate, context)
+                        break # To continue the outer while loop
+            else:
+                if (0, state) in arcs:
+                    # An accepting state, pop it and try something else
+                    self.pop()
+                    if not self.stack:
+                        # Done parsing, but another token is input
+                        raise ParseError("too much input",
+                                         type, value, context)
+                else:
+                    # No success finding a transition
+                    raise ParseError("bad input", type, value, context)
+
+    def classify(self, type, value, context):
+        """Turn a token into a label.  (Internal)"""
+        if type == token.NAME:
+            # Keep a listing of all used names
+            self.used_names.add(value)
+            # Check for reserved words
+            ilabel = self.grammar.keywords.get(value)
+            if ilabel is not None:
+                return ilabel
+        ilabel = self.grammar.tokens.get(type)
+        if ilabel is None:
+            raise ParseError("bad token", type, value, context)
+        return ilabel
+
+    def shift(self, type, value, newstate, context):
+        """Shift a token.  (Internal)"""
+        dfa, state, node = self.stack[-1]
+        newnode = (type, value, context, None)
+        newnode = self.convert(self.grammar, newnode)
+        if newnode is not None:
+            node[-1].append(newnode)
+        self.stack[-1] = (dfa, newstate, node)
+
+    def push(self, type, newdfa, newstate, context):
+        """Push a nonterminal.  (Internal)"""
+        dfa, state, node = self.stack[-1]
+        newnode = (type, None, context, [])
+        self.stack[-1] = (dfa, newstate, node)
+        self.stack.append((newdfa, 0, newnode))
+
+    def pop(self):
+        """Pop a nonterminal.  (Internal)"""
+        popdfa, popstate, popnode = self.stack.pop()
+        newnode = self.convert(self.grammar, popnode)
+        if newnode is not None:
+            if self.stack:
+                dfa, state, node = self.stack[-1]
+                node[-1].append(newnode)
+            else:
+                self.rootnode = newnode
+                self.rootnode.used_names = self.used_names
diff --git a/lib3/2to3/lib2to3/pgen2/pgen.py b/lib3/2to3/lib2to3/pgen2/pgen.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pgen2/pgen.py
@@ -0,0 +1,386 @@
+# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+# Pgen imports
+from . import grammar, token, tokenize
+
+class PgenGrammar(grammar.Grammar):
+    pass
+
+class ParserGenerator(object):
+
+    def __init__(self, filename, stream=None):
+        close_stream = None
+        if stream is None:
+            stream = open(filename)
+            close_stream = stream.close
+        self.filename = filename
+        self.stream = stream
+        self.generator = tokenize.generate_tokens(stream.readline)
+        self.gettoken() # Initialize lookahead
+        self.dfas, self.startsymbol = self.parse()
+        if close_stream is not None:
+            close_stream()
+        self.first = {} # map from symbol name to set of tokens
+        self.addfirstsets()
+
+    def make_grammar(self):
+        c = PgenGrammar()
+        names = list(self.dfas.keys())
+        names.sort()
+        names.remove(self.startsymbol)
+        names.insert(0, self.startsymbol)
+        for name in names:
+            i = 256 + len(c.symbol2number)
+            c.symbol2number[name] = i
+            c.number2symbol[i] = name
+        for name in names:
+            dfa = self.dfas[name]
+            states = []
+            for state in dfa:
+                arcs = []
+                for label, next in state.arcs.items():
+                    arcs.append((self.make_label(c, label), dfa.index(next)))
+                if state.isfinal:
+                    arcs.append((0, dfa.index(state)))
+                states.append(arcs)
+            c.states.append(states)
+            c.dfas[c.symbol2number[name]] = (states, self.make_first(c, name))
+        c.start = c.symbol2number[self.startsymbol]
+        return c
+
+    def make_first(self, c, name):
+        rawfirst = self.first[name]
+        first = {}
+        for label in rawfirst:
+            ilabel = self.make_label(c, label)
+            ##assert ilabel not in first # XXX failed on <> ... !=
+            first[ilabel] = 1
+        return first
+
+    def make_label(self, c, label):
+        # XXX Maybe this should be a method on a subclass of converter?
+        ilabel = len(c.labels)
+        if label[0].isalpha():
+            # Either a symbol name or a named token
+            if label in c.symbol2number:
+                # A symbol name (a non-terminal)
+                if label in c.symbol2label:
+                    return c.symbol2label[label]
+                else:
+                    c.labels.append((c.symbol2number[label], None))
+                    c.symbol2label[label] = ilabel
+                    return ilabel
+            else:
+                # A named token (NAME, NUMBER, STRING)
+                itoken = getattr(token, label, None)
+                assert isinstance(itoken, int), label
+                assert itoken in token.tok_name, label
+                if itoken in c.tokens:
+                    return c.tokens[itoken]
+                else:
+                    c.labels.append((itoken, None))
+                    c.tokens[itoken] = ilabel
+                    return ilabel
+        else:
+            # Either a keyword or an operator
+            assert label[0] in ('"', "'"), label
+            value = eval(label)
+            if value[0].isalpha():
+                # A keyword
+                if value in c.keywords:
+                    return c.keywords[value]
+                else:
+                    c.labels.append((token.NAME, value))
+                    c.keywords[value] = ilabel
+                    return ilabel
+            else:
+                # An operator (any non-numeric token)
+                itoken = grammar.opmap[value] # Fails if unknown token
+                if itoken in c.tokens:
+                    return c.tokens[itoken]
+                else:
+                    c.labels.append((itoken, None))
+                    c.tokens[itoken] = ilabel
+                    return ilabel
+
+    def addfirstsets(self):
+        names = list(self.dfas.keys())
+        names.sort()
+        for name in names:
+            if name not in self.first:
+                self.calcfirst(name)
+            #print name, self.first[name].keys()
+
+    def calcfirst(self, name):
+        dfa = self.dfas[name]
+        self.first[name] = None # dummy to detect left recursion
+        state = dfa[0]
+        totalset = {}
+        overlapcheck = {}
+        for label, next in state.arcs.items():
+            if label in self.dfas:
+                if label in self.first:
+                    fset = self.first[label]
+                    if fset is None:
+                        raise ValueError("recursion for rule %r" % name)
+                else:
+                    self.calcfirst(label)
+                    fset = self.first[label]
+                totalset.update(fset)
+                overlapcheck[label] = fset
+            else:
+                totalset[label] = 1
+                overlapcheck[label] = {label: 1}
+        inverse = {}
+        for label, itsfirst in overlapcheck.items():
+            for symbol in itsfirst:
+                if symbol in inverse:
+                    raise ValueError("rule %s is ambiguous; %s is in the"
+                                     " first sets of %s as well as %s" %
+                                     (name, symbol, label, inverse[symbol]))
+                inverse[symbol] = label
+        self.first[name] = totalset
+
+    def parse(self):
+        dfas = {}
+        startsymbol = None
+        # MSTART: (NEWLINE | RULE)* ENDMARKER
+        while self.type != token.ENDMARKER:
+            while self.type == token.NEWLINE:
+                self.gettoken()
+            # RULE: NAME ':' RHS NEWLINE
+            name = self.expect(token.NAME)
+            self.expect(token.OP, ":")
+            a, z = self.parse_rhs()
+            self.expect(token.NEWLINE)
+            #self.dump_nfa(name, a, z)
+            dfa = self.make_dfa(a, z)
+            #self.dump_dfa(name, dfa)
+            oldlen = len(dfa)
+            self.simplify_dfa(dfa)
+            newlen = len(dfa)
+            dfas[name] = dfa
+            #print name, oldlen, newlen
+            if startsymbol is None:
+                startsymbol = name
+        return dfas, startsymbol
+
+    def make_dfa(self, start, finish):
+        # To turn an NFA into a DFA, we define the states of the DFA
+        # to correspond to *sets* of states of the NFA.  Then do some
+        # state reduction.  Let's represent sets as dicts with 1 for
+        # values.
+        assert isinstance(start, NFAState)
+        assert isinstance(finish, NFAState)
+        def closure(state):
+            base = {}
+            addclosure(state, base)
+            return base
+        def addclosure(state, base):
+            assert isinstance(state, NFAState)
+            if state in base:
+                return
+            base[state] = 1
+            for label, next in state.arcs:
+                if label is None:
+                    addclosure(next, base)
+        states = [DFAState(closure(start), finish)]
+        for state in states: # NB states grows while we're iterating
+            arcs = {}
+            for nfastate in state.nfaset:
+                for label, next in nfastate.arcs:
+                    if label is not None:
+                        addclosure(next, arcs.setdefault(label, {}))
+            for label, nfaset in arcs.items():
+                for st in states:
+                    if st.nfaset == nfaset:
+                        break
+                else:
+                    st = DFAState(nfaset, finish)
+                    states.append(st)
+                state.addarc(st, label)
+        return states # List of DFAState instances; first one is start
+
+    def dump_nfa(self, name, start, finish):
+        print("Dump of NFA for", name)
+        todo = [start]
+        for i, state in enumerate(todo):
+            print("  State", i, state is finish and "(final)" or "")
+            for label, next in state.arcs:
+                if next in todo:
+                    j = todo.index(next)
+                else:
+                    j = len(todo)
+                    todo.append(next)
+                if label is None:
+                    print("    -> %d" % j)
+                else:
+                    print("    %s -> %d" % (label, j))
+
+    def dump_dfa(self, name, dfa):
+        print("Dump of DFA for", name)
+        for i, state in enumerate(dfa):
+            print("  State", i, state.isfinal and "(final)" or "")
+            for label, next in state.arcs.items():
+                print("    %s -> %d" % (label, dfa.index(next)))
+
+    def simplify_dfa(self, dfa):
+        # This is not theoretically optimal, but works well enough.
+        # Algorithm: repeatedly look for two states that have the same
+        # set of arcs (same labels pointing to the same nodes) and
+        # unify them, until things stop changing.
+
+        # dfa is a list of DFAState instances
+        changes = True
+        while changes:
+            changes = False
+            for i, state_i in enumerate(dfa):
+                for j in range(i+1, len(dfa)):
+                    state_j = dfa[j]
+                    if state_i == state_j:
+                        #print "  unify", i, j
+                        del dfa[j]
+                        for state in dfa:
+                            state.unifystate(state_j, state_i)
+                        changes = True
+                        break
+
+    def parse_rhs(self):
+        # RHS: ALT ('|' ALT)*
+        a, z = self.parse_alt()
+        if self.value != "|":
+            return a, z
+        else:
+            aa = NFAState()
+            zz = NFAState()
+            aa.addarc(a)
+            z.addarc(zz)
+            while self.value == "|":
+                self.gettoken()
+                a, z = self.parse_alt()
+                aa.addarc(a)
+                z.addarc(zz)
+            return aa, zz
+
+    def parse_alt(self):
+        # ALT: ITEM+
+        a, b = self.parse_item()
+        while (self.value in ("(", "[") or
+               self.type in (token.NAME, token.STRING)):
+            c, d = self.parse_item()
+            b.addarc(c)
+            b = d
+        return a, b
+
+    def parse_item(self):
+        # ITEM: '[' RHS ']' | ATOM ['+' | '*']
+        if self.value == "[":
+            self.gettoken()
+            a, z = self.parse_rhs()
+            self.expect(token.OP, "]")
+            a.addarc(z)
+            return a, z
+        else:
+            a, z = self.parse_atom()
+            value = self.value
+            if value not in ("+", "*"):
+                return a, z
+            self.gettoken()
+            z.addarc(a)
+            if value == "+":
+                return a, z
+            else:
+                return a, a
+
+    def parse_atom(self):
+        # ATOM: '(' RHS ')' | NAME | STRING
+        if self.value == "(":
+            self.gettoken()
+            a, z = self.parse_rhs()
+            self.expect(token.OP, ")")
+            return a, z
+        elif self.type in (token.NAME, token.STRING):
+            a = NFAState()
+            z = NFAState()
+            a.addarc(z, self.value)
+            self.gettoken()
+            return a, z
+        else:
+            self.raise_error("expected (...) or NAME or STRING, got %s/%s",
+                             self.type, self.value)
+
+    def expect(self, type, value=None):
+        if self.type != type or (value is not None and self.value != value):
+            self.raise_error("expected %s/%s, got %s/%s",
+                             type, value, self.type, self.value)
+        value = self.value
+        self.gettoken()
+        return value
+
+    def gettoken(self):
+        tup = next(self.generator)
+        while tup[0] in (tokenize.COMMENT, tokenize.NL):
+            tup = next(self.generator)
+        self.type, self.value, self.begin, self.end, self.line = tup
+        #print token.tok_name[self.type], repr(self.value)
+
+    def raise_error(self, msg, *args):
+        if args:
+            try:
+                msg = msg % args
+            except:
+                msg = " ".join([msg] + list(map(str, args)))
+        raise SyntaxError(msg, (self.filename, self.end[0],
+                                self.end[1], self.line))
+
+class NFAState(object):
+
+    def __init__(self):
+        self.arcs = [] # list of (label, NFAState) pairs
+
+    def addarc(self, next, label=None):
+        assert label is None or isinstance(label, str)
+        assert isinstance(next, NFAState)
+        self.arcs.append((label, next))
+
+class DFAState(object):
+
+    def __init__(self, nfaset, final):
+        assert isinstance(nfaset, dict)
+        assert isinstance(next(iter(nfaset)), NFAState)
+        assert isinstance(final, NFAState)
+        self.nfaset = nfaset
+        self.isfinal = final in nfaset
+        self.arcs = {} # map from label to DFAState
+
+    def addarc(self, next, label):
+        assert isinstance(label, str)
+        assert label not in self.arcs
+        assert isinstance(next, DFAState)
+        self.arcs[label] = next
+
+    def unifystate(self, old, new):
+        for label, next in self.arcs.items():
+            if next is old:
+                self.arcs[label] = new
+
+    def __eq__(self, other):
+        # Equality test -- ignore the nfaset instance variable
+        assert isinstance(other, DFAState)
+        if self.isfinal != other.isfinal:
+            return False
+        # Can't just return self.arcs == other.arcs, because that
+        # would invoke this method recursively, with cycles...
+        if len(self.arcs) != len(other.arcs):
+            return False
+        for label, next in self.arcs.items():
+            if next is not other.arcs.get(label):
+                return False
+        return True
+
+    __hash__ = None # For Py3 compatibility.
+
+def generate_grammar(filename="Grammar.txt"):
+    p = ParserGenerator(filename)
+    return p.make_grammar()
diff --git a/lib3/2to3/lib2to3/pgen2/token.py b/lib3/2to3/lib2to3/pgen2/token.py
new file mode 100755
--- /dev/null
+++ b/lib3/2to3/lib2to3/pgen2/token.py
@@ -0,0 +1,82 @@
+#! /usr/bin/env python
+
+"""Token constants (from "token.h")."""
+
+#  Taken from Python (r53757) and modified to include some tokens
+#   originally monkeypatched in by pgen2.tokenize
+
+#--start constants--
+ENDMARKER = 0
+NAME = 1
+NUMBER = 2
+STRING = 3
+NEWLINE = 4
+INDENT = 5
+DEDENT = 6
+LPAR = 7
+RPAR = 8
+LSQB = 9
+RSQB = 10
+COLON = 11
+COMMA = 12
+SEMI = 13
+PLUS = 14
+MINUS = 15
+STAR = 16
+SLASH = 17
+VBAR = 18
+AMPER = 19
+LESS = 20
+GREATER = 21
+EQUAL = 22
+DOT = 23
+PERCENT = 24
+BACKQUOTE = 25
+LBRACE = 26
+RBRACE = 27
+EQEQUAL = 28
+NOTEQUAL = 29
+LESSEQUAL = 30
+GREATEREQUAL = 31
+TILDE = 32
+CIRCUMFLEX = 33
+LEFTSHIFT = 34
+RIGHTSHIFT = 35
+DOUBLESTAR = 36
+PLUSEQUAL = 37
+MINEQUAL = 38
+STAREQUAL = 39
+SLASHEQUAL = 40
+PERCENTEQUAL = 41
+AMPEREQUAL = 42
+VBAREQUAL = 43
+CIRCUMFLEXEQUAL = 44
+LEFTSHIFTEQUAL = 45
+RIGHTSHIFTEQUAL = 46
+DOUBLESTAREQUAL = 47
+DOUBLESLASH = 48
+DOUBLESLASHEQUAL = 49
+AT = 50
+OP = 51
+COMMENT = 52
+NL = 53
+RARROW = 54
+ERRORTOKEN = 55
+N_TOKENS = 56
+NT_OFFSET = 256
+#--end constants--
+
+tok_name = {}
+for _name, _value in list(globals().items()):
+    if type(_value) is type(0):
+        tok_name[_value] = _name
+
+
+def ISTERMINAL(x):
+    return x < NT_OFFSET
+
+def ISNONTERMINAL(x):
+    return x >= NT_OFFSET
+
+def ISEOF(x):
+    return x == ENDMARKER
diff --git a/lib3/2to3/lib2to3/pgen2/tokenize.py b/lib3/2to3/lib2to3/pgen2/tokenize.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pgen2/tokenize.py
@@ -0,0 +1,500 @@
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation.
+# All rights reserved.
+
+"""Tokenization help for Python programs.
+
+generate_tokens(readline) is a generator that breaks a stream of
+text into Python tokens.  It accepts a readline-like method which is called
+repeatedly to get the next line of input (or "" for EOF).  It generates
+5-tuples with these members:
+
+    the token type (see token.py)
+    the token (a string)
+    the starting (row, column) indices of the token (a 2-tuple of ints)
+    the ending (row, column) indices of the token (a 2-tuple of ints)
+    the original line (string)
+
+It is designed to match the working of the Python tokenizer exactly, except
+that it produces COMMENT tokens for comments and gives type OP for all
+operators
+
+Older entry points
+    tokenize_loop(readline, tokeneater)
+    tokenize(readline, tokeneater=printtoken)
+are the same, except instead of generating tokens, tokeneater is a callback
+function to which the 5 fields described above are passed as 5 arguments,
+each time a new token is found."""
+
+__author__ = 'Ka-Ping Yee <ping at lfw.org>'
+__credits__ = \
+    'GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, Skip Montanaro'
+
+import string, re
+from codecs import BOM_UTF8, lookup
+from lib2to3.pgen2.token import *
+
+from . import token
+__all__ = [x for x in dir(token) if x[0] != '_'] + ["tokenize",
+           "generate_tokens", "untokenize"]
+del token
+
+try:
+    bytes
+except NameError:
+    # Support bytes type in Python <= 2.5, so 2to3 turns itself into
+    # valid Python 3 code.
+    bytes = str
+
+def group(*choices): return '(' + '|'.join(choices) + ')'
+def any(*choices): return group(*choices) + '*'
+def maybe(*choices): return group(*choices) + '?'
+
+Whitespace = r'[ \f\t]*'
+Comment = r'#[^\r\n]*'
+Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment)
+Name = r'[a-zA-Z_]\w*'
+
+Binnumber = r'0[bB][01]*'
+Hexnumber = r'0[xX][\da-fA-F]*[lL]?'
+Octnumber = r'0[oO]?[0-7]*[lL]?'
+Decnumber = r'[1-9]\d*[lL]?'
+Intnumber = group(Binnumber, Hexnumber, Octnumber, Decnumber)
+Exponent = r'[eE][-+]?\d+'
+Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent)
+Expfloat = r'\d+' + Exponent
+Floatnumber = group(Pointfloat, Expfloat)
+Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]')
+Number = group(Imagnumber, Floatnumber, Intnumber)
+
+# Tail end of ' string.
+Single = r"[^'\\]*(?:\\.[^'\\]*)*'"
+# Tail end of " string.
+Double = r'[^"\\]*(?:\\.[^"\\]*)*"'
+# Tail end of ''' string.
+Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''"
+# Tail end of """ string.
+Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
+Triple = group("[ubUB]?[rR]?'''", '[ubUB]?[rR]?"""')
+# Single-line ' or " string.
+String = group(r"[uU]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'",
+               r'[uU]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"')
+
+# Because of leftmost-then-longest match semantics, be sure to put the
+# longest operators first (e.g., if = came before ==, == would get
+# recognized as two instances of =).
+Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=",
+                 r"//=?", r"->",
+                 r"[+\-*/%&|^=<>]=?",
+                 r"~")
+
+Bracket = '[][(){}]'
+Special = group(r'\r?\n', r'[:;.,`@]')
+Funny = group(Operator, Bracket, Special)
+
+PlainToken = group(Number, Funny, String, Name)
+Token = Ignore + PlainToken
+
+# First (or only) line of ' or " string.
+ContStr = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" +
+                group("'", r'\\\r?\n'),
+                r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' +
+                group('"', r'\\\r?\n'))
+PseudoExtras = group(r'\\\r?\n', Comment, Triple)
+PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name)
+
+tokenprog, pseudoprog, single3prog, double3prog = list(map(
+    re.compile, (Token, PseudoToken, Single3, Double3)))
+endprogs = {"'": re.compile(Single), '"': re.compile(Double),
+            "'''": single3prog, '"""': double3prog,
+            "r'''": single3prog, 'r"""': double3prog,
+            "u'''": single3prog, 'u"""': double3prog,
+            "b'''": single3prog, 'b"""': double3prog,
+            "ur'''": single3prog, 'ur"""': double3prog,
+            "br'''": single3prog, 'br"""': double3prog,
+            "R'''": single3prog, 'R"""': double3prog,
+            "U'''": single3prog, 'U"""': double3prog,
+            "B'''": single3prog, 'B"""': double3prog,
+            "uR'''": single3prog, 'uR"""': double3prog,
+            "Ur'''": single3prog, 'Ur"""': double3prog,
+            "UR'''": single3prog, 'UR"""': double3prog,
+            "bR'''": single3prog, 'bR"""': double3prog,
+            "Br'''": single3prog, 'Br"""': double3prog,
+            "BR'''": single3prog, 'BR"""': double3prog,
+            'r': None, 'R': None,
+            'u': None, 'U': None,
+            'b': None, 'B': None}
+
+triple_quoted = {}
+for t in ("'''", '"""',
+          "r'''", 'r"""', "R'''", 'R"""',
+          "u'''", 'u"""', "U'''", 'U"""',
+          "b'''", 'b"""', "B'''", 'B"""',
+          "ur'''", 'ur"""', "Ur'''", 'Ur"""',
+          "uR'''", 'uR"""', "UR'''", 'UR"""',
+          "br'''", 'br"""', "Br'''", 'Br"""',
+          "bR'''", 'bR"""', "BR'''", 'BR"""',):
+    triple_quoted[t] = t
+single_quoted = {}
+for t in ("'", '"',
+          "r'", 'r"', "R'", 'R"',
+          "u'", 'u"', "U'", 'U"',
+          "b'", 'b"', "B'", 'B"',
+          "ur'", 'ur"', "Ur'", 'Ur"',
+          "uR'", 'uR"', "UR'", 'UR"',
+          "br'", 'br"', "Br'", 'Br"',
+          "bR'", 'bR"', "BR'", 'BR"', ):
+    single_quoted[t] = t
+
+tabsize = 8
+
+class TokenError(Exception): pass
+
+class StopTokenizing(Exception): pass
+
+def printtoken(type, token, xxx_todo_changeme, xxx_todo_changeme1, line): # for testing
+    (srow, scol) = xxx_todo_changeme
+    (erow, ecol) = xxx_todo_changeme1
+    print("%d,%d-%d,%d:\t%s\t%s" % \
+        (srow, scol, erow, ecol, tok_name[type], repr(token)))
+
+def tokenize(readline, tokeneater=printtoken):
+    """
+    The tokenize() function accepts two parameters: one representing the
+    input stream, and one providing an output mechanism for tokenize().
+
+    The first parameter, readline, must be a callable object which provides
+    the same interface as the readline() method of built-in file objects.
+    Each call to the function should return one line of input as a string.
+
+    The second parameter, tokeneater, must also be a callable object. It is
+    called once for each token, with five arguments, corresponding to the
+    tuples generated by generate_tokens().
+    """
+    try:
+        tokenize_loop(readline, tokeneater)
+    except StopTokenizing:
+        pass
+
+# backwards compatible interface
+def tokenize_loop(readline, tokeneater):
+    for token_info in generate_tokens(readline):
+        tokeneater(*token_info)
+
+class Untokenizer:
+
+    def __init__(self):
+        self.tokens = []
+        self.prev_row = 1
+        self.prev_col = 0
+
+    def add_whitespace(self, start):
+        row, col = start
+        assert row <= self.prev_row
+        col_offset = col - self.prev_col
+        if col_offset:
+            self.tokens.append(" " * col_offset)
+
+    def untokenize(self, iterable):
+        for t in iterable:
+            if len(t) == 2:
+                self.compat(t, iterable)
+                break
+            tok_type, token, start, end, line = t
+            self.add_whitespace(start)
+            self.tokens.append(token)
+            self.prev_row, self.prev_col = end
+            if tok_type in (NEWLINE, NL):
+                self.prev_row += 1
+                self.prev_col = 0
+        return "".join(self.tokens)
+
+    def compat(self, token, iterable):
+        startline = False
+        indents = []
+        toks_append = self.tokens.append
+        toknum, tokval = token
+        if toknum in (NAME, NUMBER):
+            tokval += ' '
+        if toknum in (NEWLINE, NL):
+            startline = True
+        for tok in iterable:
+            toknum, tokval = tok[:2]
+
+            if toknum in (NAME, NUMBER):
+                tokval += ' '
+
+            if toknum == INDENT:
+                indents.append(tokval)
+                continue
+            elif toknum == DEDENT:
+                indents.pop()
+                continue
+            elif toknum in (NEWLINE, NL):
+                startline = True
+            elif startline and indents:
+                toks_append(indents[-1])
+                startline = False
+            toks_append(tokval)
+
+cookie_re = re.compile("coding[:=]\s*([-\w.]+)")
+
+def _get_normal_name(orig_enc):
+    """Imitates get_normal_name in tokenizer.c."""
+    # Only care about the first 12 characters.
+    enc = orig_enc[:12].lower().replace("_", "-")
+    if enc == "utf-8" or enc.startswith("utf-8-"):
+        return "utf-8"
+    if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
+       enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
+        return "iso-8859-1"
+    return orig_enc
+
+def detect_encoding(readline):
+    """
+    The detect_encoding() function is used to detect the encoding that should
+    be used to decode a Python source file. It requires one argment, readline,
+    in the same way as the tokenize() generator.
+
+    It will call readline a maximum of twice, and return the encoding used
+    (as a string) and a list of any lines (left as bytes) it has read
+    in.
+
+    It detects the encoding from the presence of a utf-8 bom or an encoding
+    cookie as specified in pep-0263. If both a bom and a cookie are present, but
+    disagree, a SyntaxError will be raised. If the encoding cookie is an invalid
+    charset, raise a SyntaxError.  Note that if a utf-8 bom is found,
+    'utf-8-sig' is returned.
+
+    If no encoding is specified, then the default of 'utf-8' will be returned.
+    """
+    bom_found = False
+    encoding = None
+    default = 'utf-8'
+    def read_or_stop():
+        try:
+            return readline()
+        except StopIteration:
+            return bytes()
+
+    def find_cookie(line):
+        try:
+            line_string = line.decode('ascii')
+        except UnicodeDecodeError:
+            return None
+
+        matches = cookie_re.findall(line_string)
+        if not matches:
+            return None
+        encoding = _get_normal_name(matches[0])
+        try:
+            codec = lookup(encoding)
+        except LookupError:
+            # This behaviour mimics the Python interpreter
+            raise SyntaxError("unknown encoding: " + encoding)
+
+        if bom_found:
+            if codec.name != 'utf-8':
+                # This behaviour mimics the Python interpreter
+                raise SyntaxError('encoding problem: utf-8')
+            encoding += '-sig'
+        return encoding
+
+    first = read_or_stop()
+    if first.startswith(BOM_UTF8):
+        bom_found = True
+        first = first[3:]
+        default = 'utf-8-sig'
+    if not first:
+        return default, []
+
+    encoding = find_cookie(first)
+    if encoding:
+        return encoding, [first]
+
+    second = read_or_stop()
+    if not second:
+        return default, [first]
+
+    encoding = find_cookie(second)
+    if encoding:
+        return encoding, [first, second]
+
+    return default, [first, second]
+
+def untokenize(iterable):
+    """Transform tokens back into Python source code.
+
+    Each element returned by the iterable must be a token sequence
+    with at least two elements, a token number and token value.  If
+    only two tokens are passed, the resulting output is poor.
+
+    Round-trip invariant for full input:
+        Untokenized source will match input source exactly
+
+    Round-trip invariant for limited intput:
+        # Output text will tokenize the back to the input
+        t1 = [tok[:2] for tok in generate_tokens(f.readline)]
+        newcode = untokenize(t1)
+        readline = iter(newcode.splitlines(1)).next
+        t2 = [tok[:2] for tokin generate_tokens(readline)]
+        assert t1 == t2
+    """
+    ut = Untokenizer()
+    return ut.untokenize(iterable)
+
+def generate_tokens(readline):
+    """
+    The generate_tokens() generator requires one argment, readline, which
+    must be a callable object which provides the same interface as the
+    readline() method of built-in file objects. Each call to the function
+    should return one line of input as a string.  Alternately, readline
+    can be a callable function terminating with StopIteration:
+        readline = open(myfile).next    # Example of alternate readline
+
+    The generator produces 5-tuples with these members: the token type; the
+    token string; a 2-tuple (srow, scol) of ints specifying the row and
+    column where the token begins in the source; a 2-tuple (erow, ecol) of
+    ints specifying the row and column where the token ends in the source;
+    and the line on which the token was found. The line passed is the
+    logical line; continuation lines are included.
+    """
+    lnum = parenlev = continued = 0
+    namechars, numchars = string.ascii_letters + '_', '0123456789'
+    contstr, needcont = '', 0
+    contline = None
+    indents = [0]
+
+    while 1:                                   # loop over lines in stream
+        try:
+            line = readline()
+        except StopIteration:
+            line = ''
+        lnum = lnum + 1
+        pos, max = 0, len(line)
+
+        if contstr:                            # continued string
+            if not line:
+                raise TokenError("EOF in multi-line string", strstart)
+            endmatch = endprog.match(line)
+            if endmatch:
+                pos = end = endmatch.end(0)
+                yield (STRING, contstr + line[:end],
+                       strstart, (lnum, end), contline + line)
+                contstr, needcont = '', 0
+                contline = None
+            elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n':
+                yield (ERRORTOKEN, contstr + line,
+                           strstart, (lnum, len(line)), contline)
+                contstr = ''
+                contline = None
+                continue
+            else:
+                contstr = contstr + line
+                contline = contline + line
+                continue
+
+        elif parenlev == 0 and not continued:  # new statement
+            if not line: break
+            column = 0
+            while pos < max:                   # measure leading whitespace
+                if line[pos] == ' ': column = column + 1
+                elif line[pos] == '\t': column = (column//tabsize + 1)*tabsize
+                elif line[pos] == '\f': column = 0
+                else: break
+                pos = pos + 1
+            if pos == max: break
+
+            if line[pos] in '#\r\n':           # skip comments or blank lines
+                if line[pos] == '#':
+                    comment_token = line[pos:].rstrip('\r\n')
+                    nl_pos = pos + len(comment_token)
+                    yield (COMMENT, comment_token,
+                           (lnum, pos), (lnum, pos + len(comment_token)), line)
+                    yield (NL, line[nl_pos:],
+                           (lnum, nl_pos), (lnum, len(line)), line)
+                else:
+                    yield ((NL, COMMENT)[line[pos] == '#'], line[pos:],
+                           (lnum, pos), (lnum, len(line)), line)
+                continue
+
+            if column > indents[-1]:           # count indents or dedents
+                indents.append(column)
+                yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line)
+            while column < indents[-1]:
+                if column not in indents:
+                    raise IndentationError(
+                        "unindent does not match any outer indentation level",
+                        ("<tokenize>", lnum, pos, line))
+                indents = indents[:-1]
+                yield (DEDENT, '', (lnum, pos), (lnum, pos), line)
+
+        else:                                  # continued statement
+            if not line:
+                raise TokenError("EOF in multi-line statement", (lnum, 0))
+            continued = 0
+
+        while pos < max:
+            pseudomatch = pseudoprog.match(line, pos)
+            if pseudomatch:                                # scan for tokens
+                start, end = pseudomatch.span(1)
+                spos, epos, pos = (lnum, start), (lnum, end), end
+                token, initial = line[start:end], line[start]
+
+                if initial in numchars or \
+                   (initial == '.' and token != '.'):      # ordinary number
+                    yield (NUMBER, token, spos, epos, line)
+                elif initial in '\r\n':
+                    newline = NEWLINE
+                    if parenlev > 0:
+                        newline = NL
+                    yield (newline, token, spos, epos, line)
+                elif initial == '#':
+                    assert not token.endswith("\n")
+                    yield (COMMENT, token, spos, epos, line)
+                elif token in triple_quoted:
+                    endprog = endprogs[token]
+                    endmatch = endprog.match(line, pos)
+                    if endmatch:                           # all on one line
+                        pos = endmatch.end(0)
+                        token = line[start:pos]
+                        yield (STRING, token, spos, (lnum, pos), line)
+                    else:
+                        strstart = (lnum, start)           # multiple lines
+                        contstr = line[start:]
+                        contline = line
+                        break
+                elif initial in single_quoted or \
+                    token[:2] in single_quoted or \
+                    token[:3] in single_quoted:
+                    if token[-1] == '\n':                  # continued string
+                        strstart = (lnum, start)
+                        endprog = (endprogs[initial] or endprogs[token[1]] or
+                                   endprogs[token[2]])
+                        contstr, needcont = line[start:], 1
+                        contline = line
+                        break
+                    else:                                  # ordinary string
+                        yield (STRING, token, spos, epos, line)
+                elif initial in namechars:                 # ordinary name
+                    yield (NAME, token, spos, epos, line)
+                elif initial == '\\':                      # continued stmt
+                    # This yield is new; needed for better idempotency:
+                    yield (NL, token, spos, (lnum, pos), line)
+                    continued = 1
+                else:
+                    if initial in '([{': parenlev = parenlev + 1
+                    elif initial in ')]}': parenlev = parenlev - 1
+                    yield (OP, token, spos, epos, line)
+            else:
+                yield (ERRORTOKEN, line[pos],
+                           (lnum, pos), (lnum, pos+1), line)
+                pos = pos + 1
+
+    for indent in indents[1:]:                 # pop remaining indent levels
+        yield (DEDENT, '', (lnum, 0), (lnum, 0), '')
+    yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '')
+
+if __name__ == '__main__':                     # testing
+    import sys
+    if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline)
+    else: tokenize(sys.stdin.readline)
diff --git a/lib3/2to3/lib2to3/pygram.py b/lib3/2to3/lib2to3/pygram.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pygram.py
@@ -0,0 +1,40 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Export the Python grammar and symbols."""
+
+# Python imports
+import os
+
+# Local imports
+from .pgen2 import token
+from .pgen2 import driver
+from . import pytree
+
+# The grammar file
+_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__), "Grammar.txt")
+_PATTERN_GRAMMAR_FILE = os.path.join(os.path.dirname(__file__),
+                                     "PatternGrammar.txt")
+
+
+class Symbols(object):
+
+    def __init__(self, grammar):
+        """Initializer.
+
+        Creates an attribute for each grammar symbol (nonterminal),
+        whose value is the symbol's type (an int >= 256).
+        """
+        for name, symbol in grammar.symbol2number.items():
+            setattr(self, name, symbol)
+
+
+python_grammar = driver.load_grammar(_GRAMMAR_FILE)
+
+python_symbols = Symbols(python_grammar)
+
+python_grammar_no_print_statement = python_grammar.copy()
+del python_grammar_no_print_statement.keywords["print"]
+
+pattern_grammar = driver.load_grammar(_PATTERN_GRAMMAR_FILE)
+pattern_symbols = Symbols(pattern_grammar)
diff --git a/lib3/2to3/lib2to3/pytree.py b/lib3/2to3/lib2to3/pytree.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/pytree.py
@@ -0,0 +1,884 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""
+Python parse tree definitions.
+
+This is a very concrete parse tree; we need to keep every token and
+even the comments and whitespace between tokens.
+
+There's also a pattern matching implementation here.
+"""
+
+__author__ = "Guido van Rossum <guido at python.org>"
+
+import sys
+import warnings
+from io import StringIO
+
+HUGE = 0x7FFFFFFF  # maximum repeat count, default max
+
+_type_reprs = {}
+def type_repr(type_num):
+    global _type_reprs
+    if not _type_reprs:
+        from .pygram import python_symbols
+        # printing tokens is possible but not as useful
+        # from .pgen2 import token // token.__dict__.items():
+        for name, val in list(python_symbols.__dict__.items()):
+            if type(val) == int: _type_reprs[val] = name
+    return _type_reprs.setdefault(type_num, type_num)
+
+class Base(object):
+
+    """
+    Abstract base class for Node and Leaf.
+
+    This provides some default functionality and boilerplate using the
+    template pattern.
+
+    A node may be a subnode of at most one parent.
+    """
+
+    # Default values for instance variables
+    type = None    # int: token number (< 256) or symbol number (>= 256)
+    parent = None  # Parent node pointer, or None
+    children = ()  # Tuple of subnodes
+    was_changed = False
+    was_checked = False
+
+    def __new__(cls, *args, **kwds):
+        """Constructor that prevents Base from being instantiated."""
+        assert cls is not Base, "Cannot instantiate Base"
+        return object.__new__(cls)
+
+    def __eq__(self, other):
+        """
+        Compare two nodes for equality.
+
+        This calls the method _eq().
+        """
+        if self.__class__ is not other.__class__:
+            return NotImplemented
+        return self._eq(other)
+
+    __hash__ = None # For Py3 compatibility.
+
+    def __ne__(self, other):
+        """
+        Compare two nodes for inequality.
+
+        This calls the method _eq().
+        """
+        if self.__class__ is not other.__class__:
+            return NotImplemented
+        return not self._eq(other)
+
+    def _eq(self, other):
+        """
+        Compare two nodes for equality.
+
+        This is called by __eq__ and __ne__.  It is only called if the two nodes
+        have the same type.  This must be implemented by the concrete subclass.
+        Nodes should be considered equal if they have the same structure,
+        ignoring the prefix string and other context information.
+        """
+        raise NotImplementedError
+
+    def clone(self):
+        """
+        Return a cloned (deep) copy of self.
+
+        This must be implemented by the concrete subclass.
+        """
+        raise NotImplementedError
+
+    def post_order(self):
+        """
+        Return a post-order iterator for the tree.
+
+        This must be implemented by the concrete subclass.
+        """
+        raise NotImplementedError
+
+    def pre_order(self):
+        """
+        Return a pre-order iterator for the tree.
+
+        This must be implemented by the concrete subclass.
+        """
+        raise NotImplementedError
+
+    def set_prefix(self, prefix):
+        """
+        Set the prefix for the node (see Leaf class).
+
+        DEPRECATED; use the prefix property directly.
+        """
+        warnings.warn("set_prefix() is deprecated; use the prefix property",
+                      DeprecationWarning, stacklevel=2)
+        self.prefix = prefix
+
+    def get_prefix(self):
+        """
+        Return the prefix for the node (see Leaf class).
+
+        DEPRECATED; use the prefix property directly.
+        """
+        warnings.warn("get_prefix() is deprecated; use the prefix property",
+                      DeprecationWarning, stacklevel=2)
+        return self.prefix
+
+    def replace(self, new):
+        """Replace this node with a new one in the parent."""
+        assert self.parent is not None, str(self)
+        assert new is not None
+        if not isinstance(new, list):
+            new = [new]
+        l_children = []
+        found = False
+        for ch in self.parent.children:
+            if ch is self:
+                assert not found, (self.parent.children, self, new)
+                if new is not None:
+                    l_children.extend(new)
+                found = True
+            else:
+                l_children.append(ch)
+        assert found, (self.children, self, new)
+        self.parent.changed()
+        self.parent.children = l_children
+        for x in new:
+            x.parent = self.parent
+        self.parent = None
+
+    def get_lineno(self):
+        """Return the line number which generated the invocant node."""
+        node = self
+        while not isinstance(node, Leaf):
+            if not node.children:
+                return
+            node = node.children[0]
+        return node.lineno
+
+    def changed(self):
+        if self.parent:
+            self.parent.changed()
+        self.was_changed = True
+
+    def remove(self):
+        """
+        Remove the node from the tree. Returns the position of the node in its
+        parent's children before it was removed.
+        """
+        if self.parent:
+            for i, node in enumerate(self.parent.children):
+                if node is self:
+                    self.parent.changed()
+                    del self.parent.children[i]
+                    self.parent = None
+                    return i
+
+    @property
+    def next_sibling(self):
+        """
+        The node immediately following the invocant in their parent's children
+        list. If the invocant does not have a next sibling, it is None
+        """
+        if self.parent is None:
+            return None
+
+        # Can't use index(); we need to test by identity
+        for i, child in enumerate(self.parent.children):
+            if child is self:
+                try:
+                    return self.parent.children[i+1]
+                except IndexError:
+                    return None
+
+    @property
+    def prev_sibling(self):
+        """
+        The node immediately preceding the invocant in their parent's children
+        list. If the invocant does not have a previous sibling, it is None.
+        """
+        if self.parent is None:
+            return None
+
+        # Can't use index(); we need to test by identity
+        for i, child in enumerate(self.parent.children):
+            if child is self:
+                if i == 0:
+                    return None
+                return self.parent.children[i-1]
+
+    def leaves(self):
+        for child in self.children:
+            for x in child.leaves():
+                yield x
+
+    def depth(self):
+        if self.parent is None:
+            return 0
+        return 1 + self.parent.depth()
+
+    def get_suffix(self):
+        """
+        Return the string immediately following the invocant node. This is
+        effectively equivalent to node.next_sibling.prefix
+        """
+        next_sib = self.next_sibling
+        if next_sib is None:
+            return ""
+        return next_sib.prefix
+
+    if sys.version_info < (3, 0):
+        def __str__(self):
+            return str(self).encode("ascii")
+
+class Node(Base):
+
+    """Concrete implementation for interior nodes."""
+
+    def __init__(self,type, children,
+                 context=None,
+                 prefix=None,
+                 fixers_applied=None):
+        """
+        Initializer.
+
+        Takes a type constant (a symbol number >= 256), a sequence of
+        child nodes, and an optional context keyword argument.
+
+        As a side effect, the parent pointers of the children are updated.
+        """
+        assert type >= 256, type
+        self.type = type
+        self.children = list(children)
+        for ch in self.children:
+            assert ch.parent is None, repr(ch)
+            ch.parent = self
+        if prefix is not None:
+            self.prefix = prefix
+        if fixers_applied:
+            self.fixers_applied = fixers_applied[:]
+        else:
+            self.fixers_applied = None
+
+    def __repr__(self):
+        """Return a canonical string representation."""
+        return "%s(%s, %r)" % (self.__class__.__name__,
+                               type_repr(self.type),
+                               self.children)
+
+    def __unicode__(self):
+        """
+        Return a pretty string representation.
+
+        This reproduces the input source exactly.
+        """
+        return "".join(map(str, self.children))
+
+    if sys.version_info > (3, 0):
+        __str__ = __unicode__
+
+    def _eq(self, other):
+        """Compare two nodes for equality."""
+        return (self.type, self.children) == (other.type, other.children)
+
+    def clone(self):
+        """Return a cloned (deep) copy of self."""
+        return Node(self.type, [ch.clone() for ch in self.children],
+                    fixers_applied=self.fixers_applied)
+
+    def post_order(self):
+        """Return a post-order iterator for the tree."""
+        for child in self.children:
+            for node in child.post_order():
+                yield node
+        yield self
+
+    def pre_order(self):
+        """Return a pre-order iterator for the tree."""
+        yield self
+        for child in self.children:
+            for node in child.pre_order():
+                yield node
+
+    def _prefix_getter(self):
+        """
+        The whitespace and comments preceding this node in the input.
+        """
+        if not self.children:
+            return ""
+        return self.children[0].prefix
+
+    def _prefix_setter(self, prefix):
+        if self.children:
+            self.children[0].prefix = prefix
+
+    prefix = property(_prefix_getter, _prefix_setter)
+
+    def set_child(self, i, child):
+        """
+        Equivalent to 'node.children[i] = child'. This method also sets the
+        child's parent attribute appropriately.
+        """
+        child.parent = self
+        self.children[i].parent = None
+        self.children[i] = child
+        self.changed()
+
+    def insert_child(self, i, child):
+        """
+        Equivalent to 'node.children.insert(i, child)'. This method also sets
+        the child's parent attribute appropriately.
+        """
+        child.parent = self
+        self.children.insert(i, child)
+        self.changed()
+
+    def append_child(self, child):
+        """
+        Equivalent to 'node.children.append(child)'. This method also sets the
+        child's parent attribute appropriately.
+        """
+        child.parent = self
+        self.children.append(child)
+        self.changed()
+
+
+class Leaf(Base):
+
+    """Concrete implementation for leaf nodes."""
+
+    # Default values for instance variables
+    _prefix = ""  # Whitespace and comments preceding this token in the input
+    lineno = 0    # Line where this token starts in the input
+    column = 0    # Column where this token tarts in the input
+
+    def __init__(self, type, value,
+                 context=None,
+                 prefix=None,
+                 fixers_applied=[]):
+        """
+        Initializer.
+
+        Takes a type constant (a token number < 256), a string value, and an
+        optional context keyword argument.
+        """
+        assert 0 <= type < 256, type
+        if context is not None:
+            self._prefix, (self.lineno, self.column) = context
+        self.type = type
+        self.value = value
+        if prefix is not None:
+            self._prefix = prefix
+        self.fixers_applied = fixers_applied[:]
+
+    def __repr__(self):
+        """Return a canonical string representation."""
+        return "%s(%r, %r)" % (self.__class__.__name__,
+                               self.type,
+                               self.value)
+
+    def __unicode__(self):
+        """
+        Return a pretty string representation.
+
+        This reproduces the input source exactly.
+        """
+        return self.prefix + str(self.value)
+
+    if sys.version_info > (3, 0):
+        __str__ = __unicode__
+
+    def _eq(self, other):
+        """Compare two nodes for equality."""
+        return (self.type, self.value) == (other.type, other.value)
+
+    def clone(self):
+        """Return a cloned (deep) copy of self."""
+        return Leaf(self.type, self.value,
+                    (self.prefix, (self.lineno, self.column)),
+                    fixers_applied=self.fixers_applied)
+
+    def leaves(self):
+        yield self
+
+    def post_order(self):
+        """Return a post-order iterator for the tree."""
+        yield self
+
+    def pre_order(self):
+        """Return a pre-order iterator for the tree."""
+        yield self
+
+    def _prefix_getter(self):
+        """
+        The whitespace and comments preceding this token in the input.
+        """
+        return self._prefix
+
+    def _prefix_setter(self, prefix):
+        self.changed()
+        self._prefix = prefix
+
+    prefix = property(_prefix_getter, _prefix_setter)
+
+def convert(gr, raw_node):
+    """
+    Convert raw node information to a Node or Leaf instance.
+
+    This is passed to the parser driver which calls it whenever a reduction of a
+    grammar rule produces a new complete node, so that the tree is build
+    strictly bottom-up.
+    """
+    type, value, context, children = raw_node
+    if children or type in gr.number2symbol:
+        # If there's exactly one child, return that child instead of
+        # creating a new node.
+        if len(children) == 1:
+            return children[0]
+        return Node(type, children, context=context)
+    else:
+        return Leaf(type, value, context=context)
+
+
+class BasePattern(object):
+
+    """
+    A pattern is a tree matching pattern.
+
+    It looks for a specific node type (token or symbol), and
+    optionally for a specific content.
+
+    This is an abstract base class.  There are three concrete
+    subclasses:
+
+    - LeafPattern matches a single leaf node;
+    - NodePattern matches a single node (usually non-leaf);
+    - WildcardPattern matches a sequence of nodes of variable length.
+    """
+
+    # Defaults for instance variables
+    type = None     # Node type (token if < 256, symbol if >= 256)
+    content = None  # Optional content matching pattern
+    name = None     # Optional name used to store match in results dict
+
+    def __new__(cls, *args, **kwds):
+        """Constructor that prevents BasePattern from being instantiated."""
+        assert cls is not BasePattern, "Cannot instantiate BasePattern"
+        return object.__new__(cls)
+
+    def __repr__(self):
+        args = [type_repr(self.type), self.content, self.name]
+        while args and args[-1] is None:
+            del args[-1]
+        return "%s(%s)" % (self.__class__.__name__, ", ".join(map(repr, args)))
+
+    def optimize(self):
+        """
+        A subclass can define this as a hook for optimizations.
+
+        Returns either self or another node with the same effect.
+        """
+        return self
+
+    def match(self, node, results=None):
+        """
+        Does this pattern exactly match a node?
+
+        Returns True if it matches, False if not.
+
+        If results is not None, it must be a dict which will be
+        updated with the nodes matching named subpatterns.
+
+        Default implementation for non-wildcard patterns.
+        """
+        if self.type is not None and node.type != self.type:
+            return False
+        if self.content is not None:
+            r = None
+            if results is not None:
+                r = {}
+            if not self._submatch(node, r):
+                return False
+            if r:
+                results.update(r)
+        if results is not None and self.name:
+            results[self.name] = node
+        return True
+
+    def match_seq(self, nodes, results=None):
+        """
+        Does this pattern exactly match a sequence of nodes?
+
+        Default implementation for non-wildcard patterns.
+        """
+        if len(nodes) != 1:
+            return False
+        return self.match(nodes[0], results)
+
+    def generate_matches(self, nodes):
+        """
+        Generator yielding all matches for this pattern.
+
+        Default implementation for non-wildcard patterns.
+        """
+        r = {}
+        if nodes and self.match(nodes[0], r):
+            yield 1, r
+
+
+class LeafPattern(BasePattern):
+
+    def __init__(self, type=None, content=None, name=None):
+        """
+        Initializer.  Takes optional type, content, and name.
+
+        The type, if given must be a token type (< 256).  If not given,
+        this matches any *leaf* node; the content may still be required.
+
+        The content, if given, must be a string.
+
+        If a name is given, the matching node is stored in the results
+        dict under that key.
+        """
+        if type is not None:
+            assert 0 <= type < 256, type
+        if content is not None:
+            assert isinstance(content, str), repr(content)
+        self.type = type
+        self.content = content
+        self.name = name
+
+    def match(self, node, results=None):
+        """Override match() to insist on a leaf node."""
+        if not isinstance(node, Leaf):
+            return False
+        return BasePattern.match(self, node, results)
+
+    def _submatch(self, node, results=None):
+        """
+        Match the pattern's content to the node's children.
+
+        This assumes the node type matches and self.content is not None.
+
+        Returns True if it matches, False if not.
+
+        If results is not None, it must be a dict which will be
+        updated with the nodes matching named subpatterns.
+
+        When returning False, the results dict may still be updated.
+        """
+        return self.content == node.value
+
+
+class NodePattern(BasePattern):
+
+    wildcards = False
+
+    def __init__(self, type=None, content=None, name=None):
+        """
+        Initializer.  Takes optional type, content, and name.
+
+        The type, if given, must be a symbol type (>= 256).  If the
+        type is None this matches *any* single node (leaf or not),
+        except if content is not None, in which it only matches
+        non-leaf nodes that also match the content pattern.
+
+        The content, if not None, must be a sequence of Patterns that
+        must match the node's children exactly.  If the content is
+        given, the type must not be None.
+
+        If a name is given, the matching node is stored in the results
+        dict under that key.
+        """
+        if type is not None:
+            assert type >= 256, type
+        if content is not None:
+            assert not isinstance(content, str), repr(content)
+            content = list(content)
+            for i, item in enumerate(content):
+                assert isinstance(item, BasePattern), (i, item)
+                if isinstance(item, WildcardPattern):
+                    self.wildcards = True
+        self.type = type
+        self.content = content
+        self.name = name
+
+    def _submatch(self, node, results=None):
+        """
+        Match the pattern's content to the node's children.
+
+        This assumes the node type matches and self.content is not None.
+
+        Returns True if it matches, False if not.
+
+        If results is not None, it must be a dict which will be
+        updated with the nodes matching named subpatterns.
+
+        When returning False, the results dict may still be updated.
+        """
+        if self.wildcards:
+            for c, r in generate_matches(self.content, node.children):
+                if c == len(node.children):
+                    if results is not None:
+                        results.update(r)
+                    return True
+            return False
+        if len(self.content) != len(node.children):
+            return False
+        for subpattern, child in zip(self.content, node.children):
+            if not subpattern.match(child, results):
+                return False
+        return True
+
+
+class WildcardPattern(BasePattern):
+
+    """
+    A wildcard pattern can match zero or more nodes.
+
+    This has all the flexibility needed to implement patterns like:
+
+    .*      .+      .?      .{m,n}
+    (a b c | d e | f)
+    (...)*  (...)+  (...)?  (...){m,n}
+
+    except it always uses non-greedy matching.
+    """
+
+    def __init__(self, content=None, min=0, max=HUGE, name=None):
+        """
+        Initializer.
+
+        Args:
+            content: optional sequence of subsequences of patterns;
+                     if absent, matches one node;
+                     if present, each subsequence is an alternative [*]
+            min: optinal minumum number of times to match, default 0
+            max: optional maximum number of times tro match, default HUGE
+            name: optional name assigned to this match
+
+        [*] Thus, if content is [[a, b, c], [d, e], [f, g, h]] this is
+            equivalent to (a b c | d e | f g h); if content is None,
+            this is equivalent to '.' in regular expression terms.
+            The min and max parameters work as follows:
+                min=0, max=maxint: .*
+                min=1, max=maxint: .+
+                min=0, max=1: .?
+                min=1, max=1: .
+            If content is not None, replace the dot with the parenthesized
+            list of alternatives, e.g. (a b c | d e | f g h)*
+        """
+        assert 0 <= min <= max <= HUGE, (min, max)
+        if content is not None:
+            content = tuple(map(tuple, content))  # Protect against alterations
+            # Check sanity of alternatives
+            assert len(content), repr(content)  # Can't have zero alternatives
+            for alt in content:
+                assert len(alt), repr(alt) # Can have empty alternatives
+        self.content = content
+        self.min = min
+        self.max = max
+        self.name = name
+
+    def optimize(self):
+        """Optimize certain stacked wildcard patterns."""
+        subpattern = None
+        if (self.content is not None and
+            len(self.content) == 1 and len(self.content[0]) == 1):
+            subpattern = self.content[0][0]
+        if self.min == 1 and self.max == 1:
+            if self.content is None:
+                return NodePattern(name=self.name)
+            if subpattern is not None and  self.name == subpattern.name:
+                return subpattern.optimize()
+        if (self.min <= 1 and isinstance(subpattern, WildcardPattern) and
+            subpattern.min <= 1 and self.name == subpattern.name):
+            return WildcardPattern(subpattern.content,
+                                   self.min*subpattern.min,
+                                   self.max*subpattern.max,
+                                   subpattern.name)
+        return self
+
+    def match(self, node, results=None):
+        """Does this pattern exactly match a node?"""
+        return self.match_seq([node], results)
+
+    def match_seq(self, nodes, results=None):
+        """Does this pattern exactly match a sequence of nodes?"""
+        for c, r in self.generate_matches(nodes):
+            if c == len(nodes):
+                if results is not None:
+                    results.update(r)
+                    if self.name:
+                        results[self.name] = list(nodes)
+                return True
+        return False
+
+    def generate_matches(self, nodes):
+        """
+        Generator yielding matches for a sequence of nodes.
+
+        Args:
+            nodes: sequence of nodes
+
+        Yields:
+            (count, results) tuples where:
+            count: the match comprises nodes[:count];
+            results: dict containing named submatches.
+        """
+        if self.content is None:
+            # Shortcut for special case (see __init__.__doc__)
+            for count in range(self.min, 1 + min(len(nodes), self.max)):
+                r = {}
+                if self.name:
+                    r[self.name] = nodes[:count]
+                yield count, r
+        elif self.name == "bare_name":
+            yield self._bare_name_matches(nodes)
+        else:
+            # The reason for this is that hitting the recursion limit usually
+            # results in some ugly messages about how RuntimeErrors are being
+            # ignored.
+            save_stderr = sys.stderr
+            sys.stderr = StringIO()
+            try:
+                for count, r in self._recursive_matches(nodes, 0):
+                    if self.name:
+                        r[self.name] = nodes[:count]
+                    yield count, r
+            except RuntimeError:
+                # We fall back to the iterative pattern matching scheme if the recursive
+                # scheme hits the recursion limit.
+                for count, r in self._iterative_matches(nodes):
+                    if self.name:
+                        r[self.name] = nodes[:count]
+                    yield count, r
+            finally:
+                sys.stderr = save_stderr
+
+    def _iterative_matches(self, nodes):
+        """Helper to iteratively yield the matches."""
+        nodelen = len(nodes)
+        if 0 >= self.min:
+            yield 0, {}
+
+        results = []
+        # generate matches that use just one alt from self.content
+        for alt in self.content:
+            for c, r in generate_matches(alt, nodes):
+                yield c, r
+                results.append((c, r))
+
+        # for each match, iterate down the nodes
+        while results:
+            new_results = []
+            for c0, r0 in results:
+                # stop if the entire set of nodes has been matched
+                if c0 < nodelen and c0 <= self.max:
+                    for alt in self.content:
+                        for c1, r1 in generate_matches(alt, nodes[c0:]):
+                            if c1 > 0:
+                                r = {}
+                                r.update(r0)
+                                r.update(r1)
+                                yield c0 + c1, r
+                                new_results.append((c0 + c1, r))
+            results = new_results
+
+    def _bare_name_matches(self, nodes):
+        """Special optimized matcher for bare_name."""
+        count = 0
+        r = {}
+        done = False
+        max = len(nodes)
+        while not done and count < max:
+            done = True
+            for leaf in self.content:
+                if leaf[0].match(nodes[count], r):
+                    count += 1
+                    done = False
+                    break
+        r[self.name] = nodes[:count]
+        return count, r
+
+    def _recursive_matches(self, nodes, count):
+        """Helper to recursively yield the matches."""
+        assert self.content is not None
+        if count >= self.min:
+            yield 0, {}
+        if count < self.max:
+            for alt in self.content:
+                for c0, r0 in generate_matches(alt, nodes):
+                    for c1, r1 in self._recursive_matches(nodes[c0:], count+1):
+                        r = {}
+                        r.update(r0)
+                        r.update(r1)
+                        yield c0 + c1, r
+
+
+class NegatedPattern(BasePattern):
+
+    def __init__(self, content=None):
+        """
+        Initializer.
+
+        The argument is either a pattern or None.  If it is None, this
+        only matches an empty sequence (effectively '$' in regex
+        lingo).  If it is not None, this matches whenever the argument
+        pattern doesn't have any matches.
+        """
+        if content is not None:
+            assert isinstance(content, BasePattern), repr(content)
+        self.content = content
+
+    def match(self, node):
+        # We never match a node in its entirety
+        return False
+
+    def match_seq(self, nodes):
+        # We only match an empty sequence of nodes in its entirety
+        return len(nodes) == 0
+
+    def generate_matches(self, nodes):
+        if self.content is None:
+            # Return a match if there is an empty sequence
+            if len(nodes) == 0:
+                yield 0, {}
+        else:
+            # Return a match if the argument pattern has no matches
+            for c, r in self.content.generate_matches(nodes):
+                return
+            yield 0, {}
+
+
+def generate_matches(patterns, nodes):
+    """
+    Generator yielding matches for a sequence of patterns and nodes.
+
+    Args:
+        patterns: a sequence of patterns
+        nodes: a sequence of nodes
+
+    Yields:
+        (count, results) tuples where:
+        count: the entire sequence of patterns matches nodes[:count];
+        results: dict containing named submatches.
+        """
+    if not patterns:
+        yield 0, {}
+    else:
+        p, rest = patterns[0], patterns[1:]
+        for c0, r0 in p.generate_matches(nodes):
+            if not rest:
+                yield c0, r0
+            else:
+                for c1, r1 in generate_matches(rest, nodes[c0:]):
+                    r = {}
+                    r.update(r0)
+                    r.update(r1)
+                    yield c0 + c1, r
diff --git a/lib3/2to3/lib2to3/refactor.py b/lib3/2to3/lib2to3/refactor.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/refactor.py
@@ -0,0 +1,741 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Refactoring framework.
+
+Used as a main program, this can refactor any number of files and/or
+recursively descend down directories.  Imported as a module, this
+provides infrastructure to write your own refactoring tool.
+"""
+
+
+
+__author__ = "Guido van Rossum <guido at python.org>"
+
+
+# Python imports
+import os
+import sys
+import logging
+import operator
+import collections
+import io
+from itertools import chain
+
+# Local imports
+from .pgen2 import driver, tokenize, token
+from .fixer_util import find_root
+from . import pytree, pygram
+from . import btm_utils as bu
+from . import btm_matcher as bm
+
+
+def get_all_fix_names(fixer_pkg, remove_prefix=True):
+    """Return a sorted list of all available fix names in the given package."""
+    pkg = __import__(fixer_pkg, [], [], ["*"])
+    fixer_dir = os.path.dirname(pkg.__file__)
+    fix_names = []
+    for name in sorted(os.listdir(fixer_dir)):
+        if name.startswith("fix_") and name.endswith(".py"):
+            if remove_prefix:
+                name = name[4:]
+            fix_names.append(name[:-3])
+    return fix_names
+
+
+class _EveryNode(Exception):
+    pass
+
+
+def _get_head_types(pat):
+    """ Accepts a pytree Pattern Node and returns a set
+        of the pattern types which will match first. """
+
+    if isinstance(pat, (pytree.NodePattern, pytree.LeafPattern)):
+        # NodePatters must either have no type and no content
+        #   or a type and content -- so they don't get any farther
+        # Always return leafs
+        if pat.type is None:
+            raise _EveryNode
+        return set([pat.type])
+
+    if isinstance(pat, pytree.NegatedPattern):
+        if pat.content:
+            return _get_head_types(pat.content)
+        raise _EveryNode # Negated Patterns don't have a type
+
+    if isinstance(pat, pytree.WildcardPattern):
+        # Recurse on each node in content
+        r = set()
+        for p in pat.content:
+            for x in p:
+                r.update(_get_head_types(x))
+        return r
+
+    raise Exception("Oh no! I don't understand pattern %s" %(pat))
+
+
+def _get_headnode_dict(fixer_list):
+    """ Accepts a list of fixers and returns a dictionary
+        of head node type --> fixer list.  """
+    head_nodes = collections.defaultdict(list)
+    every = []
+    for fixer in fixer_list:
+        if fixer.pattern:
+            try:
+                heads = _get_head_types(fixer.pattern)
+            except _EveryNode:
+                every.append(fixer)
+            else:
+                for node_type in heads:
+                    head_nodes[node_type].append(fixer)
+        else:
+            if fixer._accept_type is not None:
+                head_nodes[fixer._accept_type].append(fixer)
+            else:
+                every.append(fixer)
+    for node_type in chain(iter(pygram.python_grammar.symbol2number.values()),
+                           pygram.python_grammar.tokens):
+        head_nodes[node_type].extend(every)
+    return dict(head_nodes)
+
+
+def get_fixers_from_package(pkg_name):
+    """
+    Return the fully qualified names for fixers in the package pkg_name.
+    """
+    return [pkg_name + "." + fix_name
+            for fix_name in get_all_fix_names(pkg_name, False)]
+
+def _identity(obj):
+    return obj
+
+if sys.version_info < (3, 0):
+    import codecs
+    _open_with_encoding = codecs.open
+    # codecs.open doesn't translate newlines sadly.
+    def _from_system_newlines(input):
+        return input.replace("\r\n", "\n")
+    def _to_system_newlines(input):
+        if os.linesep != "\n":
+            return input.replace("\n", os.linesep)
+        else:
+            return input
+else:
+    _open_with_encoding = open
+    _from_system_newlines = _identity
+    _to_system_newlines = _identity
+
+
+def _detect_future_features(source):
+    have_docstring = False
+    gen = tokenize.generate_tokens(io.StringIO(source).readline)
+    def advance():
+        tok = next(gen)
+        return tok[0], tok[1]
+    ignore = frozenset((token.NEWLINE, tokenize.NL, token.COMMENT))
+    features = set()
+    try:
+        while True:
+            tp, value = advance()
+            if tp in ignore:
+                continue
+            elif tp == token.STRING:
+                if have_docstring:
+                    break
+                have_docstring = True
+            elif tp == token.NAME and value == "from":
+                tp, value = advance()
+                if tp != token.NAME or value != "__future__":
+                    break
+                tp, value = advance()
+                if tp != token.NAME or value != "import":
+                    break
+                tp, value = advance()
+                if tp == token.OP and value == "(":
+                    tp, value = advance()
+                while tp == token.NAME:
+                    features.add(value)
+                    tp, value = advance()
+                    if tp != token.OP or value != ",":
+                        break
+                    tp, value = advance()
+            else:
+                break
+    except StopIteration:
+        pass
+    return frozenset(features)
+
+
+class FixerError(Exception):
+    """A fixer could not be loaded."""
+
+
+class RefactoringTool(object):
+
+    _default_options = {"print_function" : False}
+
+    CLASS_PREFIX = "Fix" # The prefix for fixer classes
+    FILE_PREFIX = "fix_" # The prefix for modules with a fixer within
+
+    def __init__(self, fixer_names, options=None, explicit=None):
+        """Initializer.
+
+        Args:
+            fixer_names: a list of fixers to import
+            options: an dict with configuration.
+            explicit: a list of fixers to run even if they are explicit.
+        """
+        self.fixers = fixer_names
+        self.explicit = explicit or []
+        self.options = self._default_options.copy()
+        if options is not None:
+            self.options.update(options)
+        if self.options["print_function"]:
+            self.grammar = pygram.python_grammar_no_print_statement
+        else:
+            self.grammar = pygram.python_grammar
+        self.errors = []
+        self.logger = logging.getLogger("RefactoringTool")
+        self.fixer_log = []
+        self.wrote = False
+        self.driver = driver.Driver(self.grammar,
+                                    convert=pytree.convert,
+                                    logger=self.logger)
+        self.pre_order, self.post_order = self.get_fixers()
+
+
+        self.files = []  # List of files that were or should be modified
+
+        self.BM = bm.BottomMatcher()
+        self.bmi_pre_order = [] # Bottom Matcher incompatible fixers
+        self.bmi_post_order = []
+
+        for fixer in chain(self.post_order, self.pre_order):
+            if fixer.BM_compatible:
+                self.BM.add_fixer(fixer)
+                # remove fixers that will be handled by the bottom-up
+                # matcher
+            elif fixer in self.pre_order:
+                self.bmi_pre_order.append(fixer)
+            elif fixer in self.post_order:
+                self.bmi_post_order.append(fixer)
+
+        self.bmi_pre_order_heads = _get_headnode_dict(self.bmi_pre_order)
+        self.bmi_post_order_heads = _get_headnode_dict(self.bmi_post_order)
+
+
+
+    def get_fixers(self):
+        """Inspects the options to load the requested patterns and handlers.
+
+        Returns:
+          (pre_order, post_order), where pre_order is the list of fixers that
+          want a pre-order AST traversal, and post_order is the list that want
+          post-order traversal.
+        """
+        pre_order_fixers = []
+        post_order_fixers = []
+        for fix_mod_path in self.fixers:
+            mod = __import__(fix_mod_path, {}, {}, ["*"])
+            fix_name = fix_mod_path.rsplit(".", 1)[-1]
+            if fix_name.startswith(self.FILE_PREFIX):
+                fix_name = fix_name[len(self.FILE_PREFIX):]
+            parts = fix_name.split("_")
+            class_name = self.CLASS_PREFIX + "".join([p.title() for p in parts])
+            try:
+                fix_class = getattr(mod, class_name)
+            except AttributeError:
+                raise FixerError("Can't find %s.%s" % (fix_name, class_name))
+            fixer = fix_class(self.options, self.fixer_log)
+            if fixer.explicit and self.explicit is not True and \
+                    fix_mod_path not in self.explicit:
+                self.log_message("Skipping implicit fixer: %s", fix_name)
+                continue
+
+            self.log_debug("Adding transformation: %s", fix_name)
+            if fixer.order == "pre":
+                pre_order_fixers.append(fixer)
+            elif fixer.order == "post":
+                post_order_fixers.append(fixer)
+            else:
+                raise FixerError("Illegal fixer order: %r" % fixer.order)
+
+        key_func = operator.attrgetter("run_order")
+        pre_order_fixers.sort(key=key_func)
+        post_order_fixers.sort(key=key_func)
+        return (pre_order_fixers, post_order_fixers)
+
+    def log_error(self, msg, *args, **kwds):
+        """Called when an error occurs."""
+        raise
+
+    def log_message(self, msg, *args):
+        """Hook to log a message."""
+        if args:
+            msg = msg % args
+        self.logger.info(msg)
+
+    def log_debug(self, msg, *args):
+        if args:
+            msg = msg % args
+        self.logger.debug(msg)
+
+    def print_output(self, old_text, new_text, filename, equal):
+        """Called with the old version, new version, and filename of a
+        refactored file."""
+        pass
+
+    def refactor(self, items, write=False, doctests_only=False):
+        """Refactor a list of files and directories."""
+
+        for dir_or_file in items:
+            if os.path.isdir(dir_or_file):
+                self.refactor_dir(dir_or_file, write, doctests_only)
+            else:
+                self.refactor_file(dir_or_file, write, doctests_only)
+
+    def refactor_dir(self, dir_name, write=False, doctests_only=False):
+        """Descends down a directory and refactor every Python file found.
+
+        Python files are assumed to have a .py extension.
+
+        Files and subdirectories starting with '.' are skipped.
+        """
+        py_ext = os.extsep + "py"
+        for dirpath, dirnames, filenames in os.walk(dir_name):
+            self.log_debug("Descending into %s", dirpath)
+            dirnames.sort()
+            filenames.sort()
+            for name in filenames:
+                if (not name.startswith(".") and
+                    os.path.splitext(name)[1] == py_ext):
+                    fullname = os.path.join(dirpath, name)
+                    self.refactor_file(fullname, write, doctests_only)
+            # Modify dirnames in-place to remove subdirs with leading dots
+            dirnames[:] = [dn for dn in dirnames if not dn.startswith(".")]
+
+    def _read_python_source(self, filename):
+        """
+        Do our best to decode a Python source file correctly.
+        """
+        try:
+            f = open(filename, "rb")
+        except IOError as err:
+            self.log_error("Can't open %s: %s", filename, err)
+            return None, None
+        try:
+            encoding = tokenize.detect_encoding(f.readline)[0]
+        finally:
+            f.close()
+        with _open_with_encoding(filename, "r", encoding=encoding) as f:
+            return _from_system_newlines(f.read()), encoding
+
+    def refactor_file(self, filename, write=False, doctests_only=False):
+        """Refactors a file."""
+        input, encoding = self._read_python_source(filename)
+        if input is None:
+            # Reading the file failed.
+            return
+        input += "\n" # Silence certain parse errors
+        if doctests_only:
+            self.log_debug("Refactoring doctests in %s", filename)
+            output = self.refactor_docstring(input, filename)
+            if output != input:
+                self.processed_file(output, filename, input, write, encoding)
+            else:
+                self.log_debug("No doctest changes in %s", filename)
+        else:
+            tree = self.refactor_string(input, filename)
+            if tree and tree.was_changed:
+                # The [:-1] is to take off the \n we added earlier
+                self.processed_file(str(tree)[:-1], filename,
+                                    write=write, encoding=encoding)
+            else:
+                self.log_debug("No changes in %s", filename)
+
+    def refactor_string(self, data, name):
+        """Refactor a given input string.
+
+        Args:
+            data: a string holding the code to be refactored.
+            name: a human-readable name for use in error/log messages.
+
+        Returns:
+            An AST corresponding to the refactored input stream; None if
+            there were errors during the parse.
+        """
+        features = _detect_future_features(data)
+        if "print_function" in features:
+            self.driver.grammar = pygram.python_grammar_no_print_statement
+        try:
+            tree = self.driver.parse_string(data)
+        except Exception as err:
+            self.log_error("Can't parse %s: %s: %s",
+                           name, err.__class__.__name__, err)
+            return
+        finally:
+            self.driver.grammar = self.grammar
+        tree.future_features = features
+        self.log_debug("Refactoring %s", name)
+        self.refactor_tree(tree, name)
+        return tree
+
+    def refactor_stdin(self, doctests_only=False):
+        input = sys.stdin.read()
+        if doctests_only:
+            self.log_debug("Refactoring doctests in stdin")
+            output = self.refactor_docstring(input, "<stdin>")
+            if output != input:
+                self.processed_file(output, "<stdin>", input)
+            else:
+                self.log_debug("No doctest changes in stdin")
+        else:
+            tree = self.refactor_string(input, "<stdin>")
+            if tree and tree.was_changed:
+                self.processed_file(str(tree), "<stdin>", input)
+            else:
+                self.log_debug("No changes in stdin")
+
+    def refactor_tree(self, tree, name):
+        """Refactors a parse tree (modifying the tree in place).
+
+        For compatible patterns the bottom matcher module is
+        used. Otherwise the tree is traversed node-to-node for
+        matches.
+
+        Args:
+            tree: a pytree.Node instance representing the root of the tree
+                  to be refactored.
+            name: a human-readable name for this tree.
+
+        Returns:
+            True if the tree was modified, False otherwise.
+        """
+
+        for fixer in chain(self.pre_order, self.post_order):
+            fixer.start_tree(tree, name)
+
+        #use traditional matching for the incompatible fixers
+        self.traverse_by(self.bmi_pre_order_heads, tree.pre_order())
+        self.traverse_by(self.bmi_post_order_heads, tree.post_order())
+
+        # obtain a set of candidate nodes
+        match_set = self.BM.run(tree.leaves())
+
+        while any(match_set.values()):
+            for fixer in self.BM.fixers:
+                if fixer in match_set and match_set[fixer]:
+                    #sort by depth; apply fixers from bottom(of the AST) to top
+                    match_set[fixer].sort(key=pytree.Base.depth, reverse=True)
+
+                    if fixer.keep_line_order:
+                        #some fixers(eg fix_imports) must be applied
+                        #with the original file's line order
+                        match_set[fixer].sort(key=pytree.Base.get_lineno)
+
+                    for node in list(match_set[fixer]):
+                        if node in match_set[fixer]:
+                            match_set[fixer].remove(node)
+
+                        try:
+                            find_root(node)
+                        except AssertionError:
+                            # this node has been cut off from a
+                            # previous transformation ; skip
+                            continue
+
+                        if node.fixers_applied and fixer in node.fixers_applied:
+                            # do not apply the same fixer again
+                            continue
+
+                        results = fixer.match(node)
+
+                        if results:
+                            new = fixer.transform(node, results)
+                            if new is not None:
+                                node.replace(new)
+                                #new.fixers_applied.append(fixer)
+                                for node in new.post_order():
+                                    # do not apply the fixer again to
+                                    # this or any subnode
+                                    if not node.fixers_applied:
+                                        node.fixers_applied = []
+                                    node.fixers_applied.append(fixer)
+
+                                # update the original match set for
+                                # the added code
+                                new_matches = self.BM.run(new.leaves())
+                                for fxr in new_matches:
+                                    if not fxr in match_set:
+                                        match_set[fxr]=[]
+
+                                    match_set[fxr].extend(new_matches[fxr])
+
+        for fixer in chain(self.pre_order, self.post_order):
+            fixer.finish_tree(tree, name)
+        return tree.was_changed
+
+    def traverse_by(self, fixers, traversal):
+        """Traverse an AST, applying a set of fixers to each node.
+
+        This is a helper method for refactor_tree().
+
+        Args:
+            fixers: a list of fixer instances.
+            traversal: a generator that yields AST nodes.
+
+        Returns:
+            None
+        """
+        if not fixers:
+            return
+        for node in traversal:
+            for fixer in fixers[node.type]:
+                results = fixer.match(node)
+                if results:
+                    new = fixer.transform(node, results)
+                    if new is not None:
+                        node.replace(new)
+                        node = new
+
+    def processed_file(self, new_text, filename, old_text=None, write=False,
+                       encoding=None):
+        """
+        Called when a file has been refactored, and there are changes.
+        """
+        self.files.append(filename)
+        if old_text is None:
+            old_text = self._read_python_source(filename)[0]
+            if old_text is None:
+                return
+        equal = old_text == new_text
+        self.print_output(old_text, new_text, filename, equal)
+        if equal:
+            self.log_debug("No changes to %s", filename)
+            return
+        if write:
+            self.write_file(new_text, filename, old_text, encoding)
+        else:
+            self.log_debug("Not writing changes to %s", filename)
+
+    def write_file(self, new_text, filename, old_text, encoding=None):
+        """Writes a string to a file.
+
+        It first shows a unified diff between the old text and the new text, and
+        then rewrites the file; the latter is only done if the write option is
+        set.
+        """
+        try:
+            f = _open_with_encoding(filename, "w", encoding=encoding)
+        except os.error as err:
+            self.log_error("Can't create %s: %s", filename, err)
+            return
+        try:
+            f.write(_to_system_newlines(new_text))
+        except os.error as err:
+            self.log_error("Can't write %s: %s", filename, err)
+        finally:
+            f.close()
+        self.log_debug("Wrote changes to %s", filename)
+        self.wrote = True
+
+    PS1 = ">>> "
+    PS2 = "... "
+
+    def refactor_docstring(self, input, filename):
+        """Refactors a docstring, looking for doctests.
+
+        This returns a modified version of the input string.  It looks
+        for doctests, which start with a ">>>" prompt, and may be
+        continued with "..." prompts, as long as the "..." is indented
+        the same as the ">>>".
+
+        (Unfortunately we can't use the doctest module's parser,
+        since, like most parsers, it is not geared towards preserving
+        the original source.)
+        """
+        result = []
+        block = None
+        block_lineno = None
+        indent = None
+        lineno = 0
+        for line in input.splitlines(True):
+            lineno += 1
+            if line.lstrip().startswith(self.PS1):
+                if block is not None:
+                    result.extend(self.refactor_doctest(block, block_lineno,
+                                                        indent, filename))
+                block_lineno = lineno
+                block = [line]
+                i = line.find(self.PS1)
+                indent = line[:i]
+            elif (indent is not None and
+                  (line.startswith(indent + self.PS2) or
+                   line == indent + self.PS2.rstrip() + "\n")):
+                block.append(line)
+            else:
+                if block is not None:
+                    result.extend(self.refactor_doctest(block, block_lineno,
+                                                        indent, filename))
+                block = None
+                indent = None
+                result.append(line)
+        if block is not None:
+            result.extend(self.refactor_doctest(block, block_lineno,
+                                                indent, filename))
+        return "".join(result)
+
+    def refactor_doctest(self, block, lineno, indent, filename):
+        """Refactors one doctest.
+
+        A doctest is given as a block of lines, the first of which starts
+        with ">>>" (possibly indented), while the remaining lines start
+        with "..." (identically indented).
+
+        """
+        try:
+            tree = self.parse_block(block, lineno, indent)
+        except Exception as err:
+            if self.logger.isEnabledFor(logging.DEBUG):
+                for line in block:
+                    self.log_debug("Source: %s", line.rstrip("\n"))
+            self.log_error("Can't parse docstring in %s line %s: %s: %s",
+                           filename, lineno, err.__class__.__name__, err)
+            return block
+        if self.refactor_tree(tree, filename):
+            new = str(tree).splitlines(True)
+            # Undo the adjustment of the line numbers in wrap_toks() below.
+            clipped, new = new[:lineno-1], new[lineno-1:]
+            assert clipped == ["\n"] * (lineno-1), clipped
+            if not new[-1].endswith("\n"):
+                new[-1] += "\n"
+            block = [indent + self.PS1 + new.pop(0)]
+            if new:
+                block += [indent + self.PS2 + line for line in new]
+        return block
+
+    def summarize(self):
+        if self.wrote:
+            were = "were"
+        else:
+            were = "need to be"
+        if not self.files:
+            self.log_message("No files %s modified.", were)
+        else:
+            self.log_message("Files that %s modified:", were)
+            for file in self.files:
+                self.log_message(file)
+        if self.fixer_log:
+            self.log_message("Warnings/messages while refactoring:")
+            for message in self.fixer_log:
+                self.log_message(message)
+        if self.errors:
+            if len(self.errors) == 1:
+                self.log_message("There was 1 error:")
+            else:
+                self.log_message("There were %d errors:", len(self.errors))
+            for msg, args, kwds in self.errors:
+                self.log_message(msg, *args, **kwds)
+
+    def parse_block(self, block, lineno, indent):
+        """Parses a block into a tree.
+
+        This is necessary to get correct line number / offset information
+        in the parser diagnostics and embedded into the parse tree.
+        """
+        tree = self.driver.parse_tokens(self.wrap_toks(block, lineno, indent))
+        tree.future_features = frozenset()
+        return tree
+
+    def wrap_toks(self, block, lineno, indent):
+        """Wraps a tokenize stream to systematically modify start/end."""
+        tokens = tokenize.generate_tokens(self.gen_lines(block, indent).__next__)
+        for type, value, (line0, col0), (line1, col1), line_text in tokens:
+            line0 += lineno - 1
+            line1 += lineno - 1
+            # Don't bother updating the columns; this is too complicated
+            # since line_text would also have to be updated and it would
+            # still break for tokens spanning lines.  Let the user guess
+            # that the column numbers for doctests are relative to the
+            # end of the prompt string (PS1 or PS2).
+            yield type, value, (line0, col0), (line1, col1), line_text
+
+
+    def gen_lines(self, block, indent):
+        """Generates lines as expected by tokenize from a list of lines.
+
+        This strips the first len(indent + self.PS1) characters off each line.
+        """
+        prefix1 = indent + self.PS1
+        prefix2 = indent + self.PS2
+        prefix = prefix1
+        for line in block:
+            if line.startswith(prefix):
+                yield line[len(prefix):]
+            elif line == prefix.rstrip() + "\n":
+                yield "\n"
+            else:
+                raise AssertionError("line=%r, prefix=%r" % (line, prefix))
+            prefix = prefix2
+        while True:
+            yield ""
+
+
+class MultiprocessingUnsupported(Exception):
+    pass
+
+
+class MultiprocessRefactoringTool(RefactoringTool):
+
+    def __init__(self, *args, **kwargs):
+        super(MultiprocessRefactoringTool, self).__init__(*args, **kwargs)
+        self.queue = None
+        self.output_lock = None
+
+    def refactor(self, items, write=False, doctests_only=False,
+                 num_processes=1):
+        if num_processes == 1:
+            return super(MultiprocessRefactoringTool, self).refactor(
+                items, write, doctests_only)
+        try:
+            import multiprocessing
+        except ImportError:
+            raise MultiprocessingUnsupported
+        if self.queue is not None:
+            raise RuntimeError("already doing multiple processes")
+        self.queue = multiprocessing.JoinableQueue()
+        self.output_lock = multiprocessing.Lock()
+        processes = [multiprocessing.Process(target=self._child)
+                     for i in range(num_processes)]
+        try:
+            for p in processes:
+                p.start()
+            super(MultiprocessRefactoringTool, self).refactor(items, write,
+                                                              doctests_only)
+        finally:
+            self.queue.join()
+            for i in range(num_processes):
+                self.queue.put(None)
+            for p in processes:
+                if p.is_alive():
+                    p.join()
+            self.queue = None
+
+    def _child(self):
+        task = self.queue.get()
+        while task is not None:
+            args, kwargs = task
+            try:
+                super(MultiprocessRefactoringTool, self).refactor_file(
+                    *args, **kwargs)
+            finally:
+                self.queue.task_done()
+            task = self.queue.get()
+
+    def refactor_file(self, *args, **kwargs):
+        if self.queue is not None:
+            self.queue.put((args, kwargs))
+        else:
+            return super(MultiprocessRefactoringTool, self).refactor_file(
+                *args, **kwargs)
diff --git a/lib3/2to3/lib2to3/tests/__init__.py b/lib3/2to3/lib2to3/tests/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/__init__.py
@@ -0,0 +1,24 @@
+"""Make tests/ into a package. This allows us to "import tests" and
+have tests.all_tests be a TestSuite representing all test cases
+from all test_*.py files in tests/."""
+# Author: Collin Winter
+
+import os
+import os.path
+import unittest
+import types
+
+from . import support
+
+all_tests = unittest.TestSuite()
+
+tests_dir = os.path.join(os.path.dirname(__file__), '..', 'tests')
+tests = [t[0:-3] for t in os.listdir(tests_dir)
+                        if t.startswith('test_') and t.endswith('.py')]
+
+loader = unittest.TestLoader()
+
+for t in tests:
+    __import__("",globals(),locals(),[t],level=1)
+    mod = globals()[t]
+    all_tests.addTests(loader.loadTestsFromModule(mod))
diff --git a/lib3/2to3/lib2to3/tests/data/README b/lib3/2to3/lib2to3/tests/data/README
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/README
@@ -0,0 +1,6 @@
+In this directory:
+- py2_test_grammar.py -- test file that exercises most/all of Python 2.x's grammar.
+- py3_test_grammar.py -- test file that exercises most/all of Python 3.x's grammar.
+- infinite_recursion.py -- test file that causes lib2to3's faster recursive pattern matching
+  scheme to fail, but passes when lib2to3 falls back to iterative pattern matching.
+- fixes/ -- for use by test_refactor.py
diff --git a/lib3/2to3/lib2to3/tests/data/bom.py b/lib3/2to3/lib2to3/tests/data/bom.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/bom.py
@@ -0,0 +1,2 @@
+# coding: utf-8
+print("BOM BOOM!")
diff --git a/lib3/2to3/lib2to3/tests/data/crlf.py b/lib3/2to3/lib2to3/tests/data/crlf.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/crlf.py
@@ -0,0 +1,3 @@
+print("hi")
+
+print("Like bad Windows newlines?")
diff --git a/lib3/2to3/lib2to3/tests/data/different_encoding.py b/lib3/2to3/lib2to3/tests/data/different_encoding.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/different_encoding.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+print('ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ')
+
+def f(x):
+    print('%s\t->  α(%2i):%s  β(%s)')
diff --git a/lib3/2to3/lib2to3/tests/data/fixers/bad_order.py b/lib3/2to3/lib2to3/tests/data/fixers/bad_order.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/fixers/bad_order.py
@@ -0,0 +1,5 @@
+from lib2to3.fixer_base import BaseFix
+
+class FixBadOrder(BaseFix):
+
+    order = "crazy"
diff --git a/lib3/2to3/lib2to3/tests/data/fixers/myfixes/__init__.py b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/__init__.py
new file mode 100644
diff --git a/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_explicit.py b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_explicit.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_explicit.py
@@ -0,0 +1,6 @@
+from lib2to3.fixer_base import BaseFix
+
+class FixExplicit(BaseFix):
+    explicit = True
+
+    def match(self): return False
diff --git a/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_first.py b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_first.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_first.py
@@ -0,0 +1,6 @@
+from lib2to3.fixer_base import BaseFix
+
+class FixFirst(BaseFix):
+    run_order = 1
+
+    def match(self, node): return False
diff --git a/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_last.py b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_last.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_last.py
@@ -0,0 +1,7 @@
+from lib2to3.fixer_base import BaseFix
+
+class FixLast(BaseFix):
+
+    run_order = 10
+
+    def match(self, node): return False
diff --git a/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_parrot.py b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_parrot.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_parrot.py
@@ -0,0 +1,13 @@
+from lib2to3.fixer_base import BaseFix
+from lib2to3.fixer_util import Name
+
+class FixParrot(BaseFix):
+    """
+    Change functions named 'parrot' to 'cheese'.
+    """
+
+    PATTERN = """funcdef < 'def' name='parrot' any* >"""
+
+    def transform(self, node, results):
+        name = results["name"]
+        name.replace(Name("cheese", name.prefix))
diff --git a/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_preorder.py b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_preorder.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/fixers/myfixes/fix_preorder.py
@@ -0,0 +1,6 @@
+from lib2to3.fixer_base import BaseFix
+
+class FixPreorder(BaseFix):
+    order = "pre"
+
+    def match(self, node): return False
diff --git a/lib3/2to3/lib2to3/tests/data/fixers/no_fixer_cls.py b/lib3/2to3/lib2to3/tests/data/fixers/no_fixer_cls.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/fixers/no_fixer_cls.py
@@ -0,0 +1,1 @@
+# This is empty so trying to fetch the fixer class gives an AttributeError
diff --git a/lib3/2to3/lib2to3/tests/data/fixers/parrot_example.py b/lib3/2to3/lib2to3/tests/data/fixers/parrot_example.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/fixers/parrot_example.py
@@ -0,0 +1,2 @@
+def parrot():
+    pass
diff --git a/lib3/2to3/lib2to3/tests/data/infinite_recursion.py b/lib3/2to3/lib2to3/tests/data/infinite_recursion.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/infinite_recursion.py
@@ -0,0 +1,2669 @@
+# This file is used to verify that 2to3 falls back to a slower, iterative pattern matching
+# scheme in the event that the faster recursive system fails due to infinite recursion.
+from ctypes import *
+STRING = c_char_p
+
+
+OSUnknownByteOrder = 0
+UIT_PROMPT = 1
+P_PGID = 2
+P_PID = 1
+UIT_ERROR = 5
+UIT_INFO = 4
+UIT_NONE = 0
+P_ALL = 0
+UIT_VERIFY = 2
+OSBigEndian = 2
+UIT_BOOLEAN = 3
+OSLittleEndian = 1
+__darwin_nl_item = c_int
+__darwin_wctrans_t = c_int
+__darwin_wctype_t = c_ulong
+__int8_t = c_byte
+__uint8_t = c_ubyte
+__int16_t = c_short
+__uint16_t = c_ushort
+__int32_t = c_int
+__uint32_t = c_uint
+__int64_t = c_longlong
+__uint64_t = c_ulonglong
+__darwin_intptr_t = c_long
+__darwin_natural_t = c_uint
+__darwin_ct_rune_t = c_int
+class __mbstate_t(Union):
+    pass
+__mbstate_t._pack_ = 4
+__mbstate_t._fields_ = [
+    ('__mbstate8', c_char * 128),
+    ('_mbstateL', c_longlong),
+]
+assert sizeof(__mbstate_t) == 128, sizeof(__mbstate_t)
+assert alignment(__mbstate_t) == 4, alignment(__mbstate_t)
+__darwin_mbstate_t = __mbstate_t
+__darwin_ptrdiff_t = c_int
+__darwin_size_t = c_ulong
+__darwin_va_list = STRING
+__darwin_wchar_t = c_int
+__darwin_rune_t = __darwin_wchar_t
+__darwin_wint_t = c_int
+__darwin_clock_t = c_ulong
+__darwin_socklen_t = __uint32_t
+__darwin_ssize_t = c_long
+__darwin_time_t = c_long
+sig_atomic_t = c_int
+class sigcontext(Structure):
+    pass
+sigcontext._fields_ = [
+    ('sc_onstack', c_int),
+    ('sc_mask', c_int),
+    ('sc_eax', c_uint),
+    ('sc_ebx', c_uint),
+    ('sc_ecx', c_uint),
+    ('sc_edx', c_uint),
+    ('sc_edi', c_uint),
+    ('sc_esi', c_uint),
+    ('sc_ebp', c_uint),
+    ('sc_esp', c_uint),
+    ('sc_ss', c_uint),
+    ('sc_eflags', c_uint),
+    ('sc_eip', c_uint),
+    ('sc_cs', c_uint),
+    ('sc_ds', c_uint),
+    ('sc_es', c_uint),
+    ('sc_fs', c_uint),
+    ('sc_gs', c_uint),
+]
+assert sizeof(sigcontext) == 72, sizeof(sigcontext)
+assert alignment(sigcontext) == 4, alignment(sigcontext)
+u_int8_t = c_ubyte
+u_int16_t = c_ushort
+u_int32_t = c_uint
+u_int64_t = c_ulonglong
+int32_t = c_int
+register_t = int32_t
+user_addr_t = u_int64_t
+user_size_t = u_int64_t
+int64_t = c_longlong
+user_ssize_t = int64_t
+user_long_t = int64_t
+user_ulong_t = u_int64_t
+user_time_t = int64_t
+syscall_arg_t = u_int64_t
+
+# values for unnamed enumeration
+class aes_key_st(Structure):
+    pass
+aes_key_st._fields_ = [
+    ('rd_key', c_ulong * 60),
+    ('rounds', c_int),
+]
+assert sizeof(aes_key_st) == 244, sizeof(aes_key_st)
+assert alignment(aes_key_st) == 4, alignment(aes_key_st)
+AES_KEY = aes_key_st
+class asn1_ctx_st(Structure):
+    pass
+asn1_ctx_st._fields_ = [
+    ('p', POINTER(c_ubyte)),
+    ('eos', c_int),
+    ('error', c_int),
+    ('inf', c_int),
+    ('tag', c_int),
+    ('xclass', c_int),
+    ('slen', c_long),
+    ('max', POINTER(c_ubyte)),
+    ('q', POINTER(c_ubyte)),
+    ('pp', POINTER(POINTER(c_ubyte))),
+    ('line', c_int),
+]
+assert sizeof(asn1_ctx_st) == 44, sizeof(asn1_ctx_st)
+assert alignment(asn1_ctx_st) == 4, alignment(asn1_ctx_st)
+ASN1_CTX = asn1_ctx_st
+class asn1_object_st(Structure):
+    pass
+asn1_object_st._fields_ = [
+    ('sn', STRING),
+    ('ln', STRING),
+    ('nid', c_int),
+    ('length', c_int),
+    ('data', POINTER(c_ubyte)),
+    ('flags', c_int),
+]
+assert sizeof(asn1_object_st) == 24, sizeof(asn1_object_st)
+assert alignment(asn1_object_st) == 4, alignment(asn1_object_st)
+ASN1_OBJECT = asn1_object_st
+class asn1_string_st(Structure):
+    pass
+asn1_string_st._fields_ = [
+    ('length', c_int),
+    ('type', c_int),
+    ('data', POINTER(c_ubyte)),
+    ('flags', c_long),
+]
+assert sizeof(asn1_string_st) == 16, sizeof(asn1_string_st)
+assert alignment(asn1_string_st) == 4, alignment(asn1_string_st)
+ASN1_STRING = asn1_string_st
+class ASN1_ENCODING_st(Structure):
+    pass
+ASN1_ENCODING_st._fields_ = [
+    ('enc', POINTER(c_ubyte)),
+    ('len', c_long),
+    ('modified', c_int),
+]
+assert sizeof(ASN1_ENCODING_st) == 12, sizeof(ASN1_ENCODING_st)
+assert alignment(ASN1_ENCODING_st) == 4, alignment(ASN1_ENCODING_st)
+ASN1_ENCODING = ASN1_ENCODING_st
+class asn1_string_table_st(Structure):
+    pass
+asn1_string_table_st._fields_ = [
+    ('nid', c_int),
+    ('minsize', c_long),
+    ('maxsize', c_long),
+    ('mask', c_ulong),
+    ('flags', c_ulong),
+]
+assert sizeof(asn1_string_table_st) == 20, sizeof(asn1_string_table_st)
+assert alignment(asn1_string_table_st) == 4, alignment(asn1_string_table_st)
+ASN1_STRING_TABLE = asn1_string_table_st
+class ASN1_TEMPLATE_st(Structure):
+    pass
+ASN1_TEMPLATE_st._fields_ = [
+]
+ASN1_TEMPLATE = ASN1_TEMPLATE_st
+class ASN1_ITEM_st(Structure):
+    pass
+ASN1_ITEM = ASN1_ITEM_st
+ASN1_ITEM_st._fields_ = [
+]
+class ASN1_TLC_st(Structure):
+    pass
+ASN1_TLC = ASN1_TLC_st
+ASN1_TLC_st._fields_ = [
+]
+class ASN1_VALUE_st(Structure):
+    pass
+ASN1_VALUE_st._fields_ = [
+]
+ASN1_VALUE = ASN1_VALUE_st
+ASN1_ITEM_EXP = ASN1_ITEM
+class asn1_type_st(Structure):
+    pass
+class N12asn1_type_st4DOLLAR_11E(Union):
+    pass
+ASN1_BOOLEAN = c_int
+ASN1_INTEGER = asn1_string_st
+ASN1_ENUMERATED = asn1_string_st
+ASN1_BIT_STRING = asn1_string_st
+ASN1_OCTET_STRING = asn1_string_st
+ASN1_PRINTABLESTRING = asn1_string_st
+ASN1_T61STRING = asn1_string_st
+ASN1_IA5STRING = asn1_string_st
+ASN1_GENERALSTRING = asn1_string_st
+ASN1_BMPSTRING = asn1_string_st
+ASN1_UNIVERSALSTRING = asn1_string_st
+ASN1_UTCTIME = asn1_string_st
+ASN1_GENERALIZEDTIME = asn1_string_st
+ASN1_VISIBLESTRING = asn1_string_st
+ASN1_UTF8STRING = asn1_string_st
+N12asn1_type_st4DOLLAR_11E._fields_ = [
+    ('ptr', STRING),
+    ('boolean', ASN1_BOOLEAN),
+    ('asn1_string', POINTER(ASN1_STRING)),
+    ('object', POINTER(ASN1_OBJECT)),
+    ('integer', POINTER(ASN1_INTEGER)),
+    ('enumerated', POINTER(ASN1_ENUMERATED)),
+    ('bit_string', POINTER(ASN1_BIT_STRING)),
+    ('octet_string', POINTER(ASN1_OCTET_STRING)),
+    ('printablestring', POINTER(ASN1_PRINTABLESTRING)),
+    ('t61string', POINTER(ASN1_T61STRING)),
+    ('ia5string', POINTER(ASN1_IA5STRING)),
+    ('generalstring', POINTER(ASN1_GENERALSTRING)),
+    ('bmpstring', POINTER(ASN1_BMPSTRING)),
+    ('universalstring', POINTER(ASN1_UNIVERSALSTRING)),
+    ('utctime', POINTER(ASN1_UTCTIME)),
+    ('generalizedtime', POINTER(ASN1_GENERALIZEDTIME)),
+    ('visiblestring', POINTER(ASN1_VISIBLESTRING)),
+    ('utf8string', POINTER(ASN1_UTF8STRING)),
+    ('set', POINTER(ASN1_STRING)),
+    ('sequence', POINTER(ASN1_STRING)),
+]
+assert sizeof(N12asn1_type_st4DOLLAR_11E) == 4, sizeof(N12asn1_type_st4DOLLAR_11E)
+assert alignment(N12asn1_type_st4DOLLAR_11E) == 4, alignment(N12asn1_type_st4DOLLAR_11E)
+asn1_type_st._fields_ = [
+    ('type', c_int),
+    ('value', N12asn1_type_st4DOLLAR_11E),
+]
+assert sizeof(asn1_type_st) == 8, sizeof(asn1_type_st)
+assert alignment(asn1_type_st) == 4, alignment(asn1_type_st)
+ASN1_TYPE = asn1_type_st
+class asn1_method_st(Structure):
+    pass
+asn1_method_st._fields_ = [
+    ('i2d', CFUNCTYPE(c_int)),
+    ('d2i', CFUNCTYPE(STRING)),
+    ('create', CFUNCTYPE(STRING)),
+    ('destroy', CFUNCTYPE(None)),
+]
+assert sizeof(asn1_method_st) == 16, sizeof(asn1_method_st)
+assert alignment(asn1_method_st) == 4, alignment(asn1_method_st)
+ASN1_METHOD = asn1_method_st
+class asn1_header_st(Structure):
+    pass
+asn1_header_st._fields_ = [
+    ('header', POINTER(ASN1_OCTET_STRING)),
+    ('data', STRING),
+    ('meth', POINTER(ASN1_METHOD)),
+]
+assert sizeof(asn1_header_st) == 12, sizeof(asn1_header_st)
+assert alignment(asn1_header_st) == 4, alignment(asn1_header_st)
+ASN1_HEADER = asn1_header_st
+class BIT_STRING_BITNAME_st(Structure):
+    pass
+BIT_STRING_BITNAME_st._fields_ = [
+    ('bitnum', c_int),
+    ('lname', STRING),
+    ('sname', STRING),
+]
+assert sizeof(BIT_STRING_BITNAME_st) == 12, sizeof(BIT_STRING_BITNAME_st)
+assert alignment(BIT_STRING_BITNAME_st) == 4, alignment(BIT_STRING_BITNAME_st)
+BIT_STRING_BITNAME = BIT_STRING_BITNAME_st
+class bio_st(Structure):
+    pass
+BIO = bio_st
+bio_info_cb = CFUNCTYPE(None, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long)
+class bio_method_st(Structure):
+    pass
+bio_method_st._fields_ = [
+    ('type', c_int),
+    ('name', STRING),
+    ('bwrite', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)),
+    ('bread', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)),
+    ('bputs', CFUNCTYPE(c_int, POINTER(BIO), STRING)),
+    ('bgets', CFUNCTYPE(c_int, POINTER(BIO), STRING, c_int)),
+    ('ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, c_long, c_void_p)),
+    ('create', CFUNCTYPE(c_int, POINTER(BIO))),
+    ('destroy', CFUNCTYPE(c_int, POINTER(BIO))),
+    ('callback_ctrl', CFUNCTYPE(c_long, POINTER(BIO), c_int, POINTER(bio_info_cb))),
+]
+assert sizeof(bio_method_st) == 40, sizeof(bio_method_st)
+assert alignment(bio_method_st) == 4, alignment(bio_method_st)
+BIO_METHOD = bio_method_st
+class crypto_ex_data_st(Structure):
+    pass
+class stack_st(Structure):
+    pass
+STACK = stack_st
+crypto_ex_data_st._fields_ = [
+    ('sk', POINTER(STACK)),
+    ('dummy', c_int),
+]
+assert sizeof(crypto_ex_data_st) == 8, sizeof(crypto_ex_data_st)
+assert alignment(crypto_ex_data_st) == 4, alignment(crypto_ex_data_st)
+CRYPTO_EX_DATA = crypto_ex_data_st
+bio_st._fields_ = [
+    ('method', POINTER(BIO_METHOD)),
+    ('callback', CFUNCTYPE(c_long, POINTER(bio_st), c_int, STRING, c_int, c_long, c_long)),
+    ('cb_arg', STRING),
+    ('init', c_int),
+    ('shutdown', c_int),
+    ('flags', c_int),
+    ('retry_reason', c_int),
+    ('num', c_int),
+    ('ptr', c_void_p),
+    ('next_bio', POINTER(bio_st)),
+    ('prev_bio', POINTER(bio_st)),
+    ('references', c_int),
+    ('num_read', c_ulong),
+    ('num_write', c_ulong),
+    ('ex_data', CRYPTO_EX_DATA),
+]
+assert sizeof(bio_st) == 64, sizeof(bio_st)
+assert alignment(bio_st) == 4, alignment(bio_st)
+class bio_f_buffer_ctx_struct(Structure):
+    pass
+bio_f_buffer_ctx_struct._fields_ = [
+    ('ibuf_size', c_int),
+    ('obuf_size', c_int),
+    ('ibuf', STRING),
+    ('ibuf_len', c_int),
+    ('ibuf_off', c_int),
+    ('obuf', STRING),
+    ('obuf_len', c_int),
+    ('obuf_off', c_int),
+]
+assert sizeof(bio_f_buffer_ctx_struct) == 32, sizeof(bio_f_buffer_ctx_struct)
+assert alignment(bio_f_buffer_ctx_struct) == 4, alignment(bio_f_buffer_ctx_struct)
+BIO_F_BUFFER_CTX = bio_f_buffer_ctx_struct
+class hostent(Structure):
+    pass
+hostent._fields_ = [
+]
+class bf_key_st(Structure):
+    pass
+bf_key_st._fields_ = [
+    ('P', c_uint * 18),
+    ('S', c_uint * 1024),
+]
+assert sizeof(bf_key_st) == 4168, sizeof(bf_key_st)
+assert alignment(bf_key_st) == 4, alignment(bf_key_st)
+BF_KEY = bf_key_st
+class bignum_st(Structure):
+    pass
+bignum_st._fields_ = [
+    ('d', POINTER(c_ulong)),
+    ('top', c_int),
+    ('dmax', c_int),
+    ('neg', c_int),
+    ('flags', c_int),
+]
+assert sizeof(bignum_st) == 20, sizeof(bignum_st)
+assert alignment(bignum_st) == 4, alignment(bignum_st)
+BIGNUM = bignum_st
+class bignum_ctx(Structure):
+    pass
+bignum_ctx._fields_ = [
+]
+BN_CTX = bignum_ctx
+class bn_blinding_st(Structure):
+    pass
+bn_blinding_st._fields_ = [
+    ('init', c_int),
+    ('A', POINTER(BIGNUM)),
+    ('Ai', POINTER(BIGNUM)),
+    ('mod', POINTER(BIGNUM)),
+    ('thread_id', c_ulong),
+]
+assert sizeof(bn_blinding_st) == 20, sizeof(bn_blinding_st)
+assert alignment(bn_blinding_st) == 4, alignment(bn_blinding_st)
+BN_BLINDING = bn_blinding_st
+class bn_mont_ctx_st(Structure):
+    pass
+bn_mont_ctx_st._fields_ = [
+    ('ri', c_int),
+    ('RR', BIGNUM),
+    ('N', BIGNUM),
+    ('Ni', BIGNUM),
+    ('n0', c_ulong),
+    ('flags', c_int),
+]
+assert sizeof(bn_mont_ctx_st) == 72, sizeof(bn_mont_ctx_st)
+assert alignment(bn_mont_ctx_st) == 4, alignment(bn_mont_ctx_st)
+BN_MONT_CTX = bn_mont_ctx_st
+class bn_recp_ctx_st(Structure):
+    pass
+bn_recp_ctx_st._fields_ = [
+    ('N', BIGNUM),
+    ('Nr', BIGNUM),
+    ('num_bits', c_int),
+    ('shift', c_int),
+    ('flags', c_int),
+]
+assert sizeof(bn_recp_ctx_st) == 52, sizeof(bn_recp_ctx_st)
+assert alignment(bn_recp_ctx_st) == 4, alignment(bn_recp_ctx_st)
+BN_RECP_CTX = bn_recp_ctx_st
+class buf_mem_st(Structure):
+    pass
+buf_mem_st._fields_ = [
+    ('length', c_int),
+    ('data', STRING),
+    ('max', c_int),
+]
+assert sizeof(buf_mem_st) == 12, sizeof(buf_mem_st)
+assert alignment(buf_mem_st) == 4, alignment(buf_mem_st)
+BUF_MEM = buf_mem_st
+class cast_key_st(Structure):
+    pass
+cast_key_st._fields_ = [
+    ('data', c_ulong * 32),
+    ('short_key', c_int),
+]
+assert sizeof(cast_key_st) == 132, sizeof(cast_key_st)
+assert alignment(cast_key_st) == 4, alignment(cast_key_st)
+CAST_KEY = cast_key_st
+class comp_method_st(Structure):
+    pass
+comp_method_st._fields_ = [
+    ('type', c_int),
+    ('name', STRING),
+    ('init', CFUNCTYPE(c_int)),
+    ('finish', CFUNCTYPE(None)),
+    ('compress', CFUNCTYPE(c_int)),
+    ('expand', CFUNCTYPE(c_int)),
+    ('ctrl', CFUNCTYPE(c_long)),
+    ('callback_ctrl', CFUNCTYPE(c_long)),
+]
+assert sizeof(comp_method_st) == 32, sizeof(comp_method_st)
+assert alignment(comp_method_st) == 4, alignment(comp_method_st)
+COMP_METHOD = comp_method_st
+class comp_ctx_st(Structure):
+    pass
+comp_ctx_st._fields_ = [
+    ('meth', POINTER(COMP_METHOD)),
+    ('compress_in', c_ulong),
+    ('compress_out', c_ulong),
+    ('expand_in', c_ulong),
+    ('expand_out', c_ulong),
+    ('ex_data', CRYPTO_EX_DATA),
+]
+assert sizeof(comp_ctx_st) == 28, sizeof(comp_ctx_st)
+assert alignment(comp_ctx_st) == 4, alignment(comp_ctx_st)
+COMP_CTX = comp_ctx_st
+class CRYPTO_dynlock_value(Structure):
+    pass
+CRYPTO_dynlock_value._fields_ = [
+]
+class CRYPTO_dynlock(Structure):
+    pass
+CRYPTO_dynlock._fields_ = [
+    ('references', c_int),
+    ('data', POINTER(CRYPTO_dynlock_value)),
+]
+assert sizeof(CRYPTO_dynlock) == 8, sizeof(CRYPTO_dynlock)
+assert alignment(CRYPTO_dynlock) == 4, alignment(CRYPTO_dynlock)
+BIO_dummy = bio_st
+CRYPTO_EX_new = CFUNCTYPE(c_int, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p)
+CRYPTO_EX_free = CFUNCTYPE(None, c_void_p, c_void_p, POINTER(CRYPTO_EX_DATA), c_int, c_long, c_void_p)
+CRYPTO_EX_dup = CFUNCTYPE(c_int, POINTER(CRYPTO_EX_DATA), POINTER(CRYPTO_EX_DATA), c_void_p, c_int, c_long, c_void_p)
+class crypto_ex_data_func_st(Structure):
+    pass
+crypto_ex_data_func_st._fields_ = [
+    ('argl', c_long),
+    ('argp', c_void_p),
+    ('new_func', POINTER(CRYPTO_EX_new)),
+    ('free_func', POINTER(CRYPTO_EX_free)),
+    ('dup_func', POINTER(CRYPTO_EX_dup)),
+]
+assert sizeof(crypto_ex_data_func_st) == 20, sizeof(crypto_ex_data_func_st)
+assert alignment(crypto_ex_data_func_st) == 4, alignment(crypto_ex_data_func_st)
+CRYPTO_EX_DATA_FUNCS = crypto_ex_data_func_st
+class st_CRYPTO_EX_DATA_IMPL(Structure):
+    pass
+CRYPTO_EX_DATA_IMPL = st_CRYPTO_EX_DATA_IMPL
+st_CRYPTO_EX_DATA_IMPL._fields_ = [
+]
+CRYPTO_MEM_LEAK_CB = CFUNCTYPE(c_void_p, c_ulong, STRING, c_int, c_int, c_void_p)
+DES_cblock = c_ubyte * 8
+const_DES_cblock = c_ubyte * 8
+class DES_ks(Structure):
+    pass
+class N6DES_ks3DOLLAR_9E(Union):
+    pass
+N6DES_ks3DOLLAR_9E._fields_ = [
+    ('cblock', DES_cblock),
+    ('deslong', c_ulong * 2),
+]
+assert sizeof(N6DES_ks3DOLLAR_9E) == 8, sizeof(N6DES_ks3DOLLAR_9E)
+assert alignment(N6DES_ks3DOLLAR_9E) == 4, alignment(N6DES_ks3DOLLAR_9E)
+DES_ks._fields_ = [
+    ('ks', N6DES_ks3DOLLAR_9E * 16),
+]
+assert sizeof(DES_ks) == 128, sizeof(DES_ks)
+assert alignment(DES_ks) == 4, alignment(DES_ks)
+DES_key_schedule = DES_ks
+_ossl_old_des_cblock = c_ubyte * 8
+class _ossl_old_des_ks_struct(Structure):
+    pass
+class N23_ossl_old_des_ks_struct4DOLLAR_10E(Union):
+    pass
+N23_ossl_old_des_ks_struct4DOLLAR_10E._fields_ = [
+    ('_', _ossl_old_des_cblock),
+    ('pad', c_ulong * 2),
+]
+assert sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 8, sizeof(N23_ossl_old_des_ks_struct4DOLLAR_10E)
+assert alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E) == 4, alignment(N23_ossl_old_des_ks_struct4DOLLAR_10E)
+_ossl_old_des_ks_struct._fields_ = [
+    ('ks', N23_ossl_old_des_ks_struct4DOLLAR_10E),
+]
+assert sizeof(_ossl_old_des_ks_struct) == 8, sizeof(_ossl_old_des_ks_struct)
+assert alignment(_ossl_old_des_ks_struct) == 4, alignment(_ossl_old_des_ks_struct)
+_ossl_old_des_key_schedule = _ossl_old_des_ks_struct * 16
+class dh_st(Structure):
+    pass
+DH = dh_st
+class dh_method(Structure):
+    pass
+dh_method._fields_ = [
+    ('name', STRING),
+    ('generate_key', CFUNCTYPE(c_int, POINTER(DH))),
+    ('compute_key', CFUNCTYPE(c_int, POINTER(c_ubyte), POINTER(BIGNUM), POINTER(DH))),
+    ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DH), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))),
+    ('init', CFUNCTYPE(c_int, POINTER(DH))),
+    ('finish', CFUNCTYPE(c_int, POINTER(DH))),
+    ('flags', c_int),
+    ('app_data', STRING),
+]
+assert sizeof(dh_method) == 32, sizeof(dh_method)
+assert alignment(dh_method) == 4, alignment(dh_method)
+DH_METHOD = dh_method
+class engine_st(Structure):
+    pass
+ENGINE = engine_st
+dh_st._fields_ = [
+    ('pad', c_int),
+    ('version', c_int),
+    ('p', POINTER(BIGNUM)),
+    ('g', POINTER(BIGNUM)),
+    ('length', c_long),
+    ('pub_key', POINTER(BIGNUM)),
+    ('priv_key', POINTER(BIGNUM)),
+    ('flags', c_int),
+    ('method_mont_p', STRING),
+    ('q', POINTER(BIGNUM)),
+    ('j', POINTER(BIGNUM)),
+    ('seed', POINTER(c_ubyte)),
+    ('seedlen', c_int),
+    ('counter', POINTER(BIGNUM)),
+    ('references', c_int),
+    ('ex_data', CRYPTO_EX_DATA),
+    ('meth', POINTER(DH_METHOD)),
+    ('engine', POINTER(ENGINE)),
+]
+assert sizeof(dh_st) == 76, sizeof(dh_st)
+assert alignment(dh_st) == 4, alignment(dh_st)
+class dsa_st(Structure):
+    pass
+DSA = dsa_st
+class DSA_SIG_st(Structure):
+    pass
+DSA_SIG_st._fields_ = [
+    ('r', POINTER(BIGNUM)),
+    ('s', POINTER(BIGNUM)),
+]
+assert sizeof(DSA_SIG_st) == 8, sizeof(DSA_SIG_st)
+assert alignment(DSA_SIG_st) == 4, alignment(DSA_SIG_st)
+DSA_SIG = DSA_SIG_st
+class dsa_method(Structure):
+    pass
+dsa_method._fields_ = [
+    ('name', STRING),
+    ('dsa_do_sign', CFUNCTYPE(POINTER(DSA_SIG), POINTER(c_ubyte), c_int, POINTER(DSA))),
+    ('dsa_sign_setup', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BN_CTX), POINTER(POINTER(BIGNUM)), POINTER(POINTER(BIGNUM)))),
+    ('dsa_do_verify', CFUNCTYPE(c_int, POINTER(c_ubyte), c_int, POINTER(DSA_SIG), POINTER(DSA))),
+    ('dsa_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))),
+    ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(DSA), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))),
+    ('init', CFUNCTYPE(c_int, POINTER(DSA))),
+    ('finish', CFUNCTYPE(c_int, POINTER(DSA))),
+    ('flags', c_int),
+    ('app_data', STRING),
+]
+assert sizeof(dsa_method) == 40, sizeof(dsa_method)
+assert alignment(dsa_method) == 4, alignment(dsa_method)
+DSA_METHOD = dsa_method
+dsa_st._fields_ = [
+    ('pad', c_int),
+    ('version', c_long),
+    ('write_params', c_int),
+    ('p', POINTER(BIGNUM)),
+    ('q', POINTER(BIGNUM)),
+    ('g', POINTER(BIGNUM)),
+    ('pub_key', POINTER(BIGNUM)),
+    ('priv_key', POINTER(BIGNUM)),
+    ('kinv', POINTER(BIGNUM)),
+    ('r', POINTER(BIGNUM)),
+    ('flags', c_int),
+    ('method_mont_p', STRING),
+    ('references', c_int),
+    ('ex_data', CRYPTO_EX_DATA),
+    ('meth', POINTER(DSA_METHOD)),
+    ('engine', POINTER(ENGINE)),
+]
+assert sizeof(dsa_st) == 68, sizeof(dsa_st)
+assert alignment(dsa_st) == 4, alignment(dsa_st)
+class evp_pkey_st(Structure):
+    pass
+class N11evp_pkey_st4DOLLAR_12E(Union):
+    pass
+class rsa_st(Structure):
+    pass
+N11evp_pkey_st4DOLLAR_12E._fields_ = [
+    ('ptr', STRING),
+    ('rsa', POINTER(rsa_st)),
+    ('dsa', POINTER(dsa_st)),
+    ('dh', POINTER(dh_st)),
+]
+assert sizeof(N11evp_pkey_st4DOLLAR_12E) == 4, sizeof(N11evp_pkey_st4DOLLAR_12E)
+assert alignment(N11evp_pkey_st4DOLLAR_12E) == 4, alignment(N11evp_pkey_st4DOLLAR_12E)
+evp_pkey_st._fields_ = [
+    ('type', c_int),
+    ('save_type', c_int),
+    ('references', c_int),
+    ('pkey', N11evp_pkey_st4DOLLAR_12E),
+    ('save_parameters', c_int),
+    ('attributes', POINTER(STACK)),
+]
+assert sizeof(evp_pkey_st) == 24, sizeof(evp_pkey_st)
+assert alignment(evp_pkey_st) == 4, alignment(evp_pkey_st)
+class env_md_st(Structure):
+    pass
+class env_md_ctx_st(Structure):
+    pass
+EVP_MD_CTX = env_md_ctx_st
+env_md_st._fields_ = [
+    ('type', c_int),
+    ('pkey_type', c_int),
+    ('md_size', c_int),
+    ('flags', c_ulong),
+    ('init', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))),
+    ('update', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), c_void_p, c_ulong)),
+    ('final', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(c_ubyte))),
+    ('copy', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX), POINTER(EVP_MD_CTX))),
+    ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_MD_CTX))),
+    ('sign', CFUNCTYPE(c_int)),
+    ('verify', CFUNCTYPE(c_int)),
+    ('required_pkey_type', c_int * 5),
+    ('block_size', c_int),
+    ('ctx_size', c_int),
+]
+assert sizeof(env_md_st) == 72, sizeof(env_md_st)
+assert alignment(env_md_st) == 4, alignment(env_md_st)
+EVP_MD = env_md_st
+env_md_ctx_st._fields_ = [
+    ('digest', POINTER(EVP_MD)),
+    ('engine', POINTER(ENGINE)),
+    ('flags', c_ulong),
+    ('md_data', c_void_p),
+]
+assert sizeof(env_md_ctx_st) == 16, sizeof(env_md_ctx_st)
+assert alignment(env_md_ctx_st) == 4, alignment(env_md_ctx_st)
+class evp_cipher_st(Structure):
+    pass
+class evp_cipher_ctx_st(Structure):
+    pass
+EVP_CIPHER_CTX = evp_cipher_ctx_st
+evp_cipher_st._fields_ = [
+    ('nid', c_int),
+    ('block_size', c_int),
+    ('key_len', c_int),
+    ('iv_len', c_int),
+    ('flags', c_ulong),
+    ('init', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_int)),
+    ('do_cipher', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(c_ubyte), POINTER(c_ubyte), c_uint)),
+    ('cleanup', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX))),
+    ('ctx_size', c_int),
+    ('set_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))),
+    ('get_asn1_parameters', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), POINTER(ASN1_TYPE))),
+    ('ctrl', CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), c_int, c_int, c_void_p)),
+    ('app_data', c_void_p),
+]
+assert sizeof(evp_cipher_st) == 52, sizeof(evp_cipher_st)
+assert alignment(evp_cipher_st) == 4, alignment(evp_cipher_st)
+class evp_cipher_info_st(Structure):
+    pass
+EVP_CIPHER = evp_cipher_st
+evp_cipher_info_st._fields_ = [
+    ('cipher', POINTER(EVP_CIPHER)),
+    ('iv', c_ubyte * 16),
+]
+assert sizeof(evp_cipher_info_st) == 20, sizeof(evp_cipher_info_st)
+assert alignment(evp_cipher_info_st) == 4, alignment(evp_cipher_info_st)
+EVP_CIPHER_INFO = evp_cipher_info_st
+evp_cipher_ctx_st._fields_ = [
+    ('cipher', POINTER(EVP_CIPHER)),
+    ('engine', POINTER(ENGINE)),
+    ('encrypt', c_int),
+    ('buf_len', c_int),
+    ('oiv', c_ubyte * 16),
+    ('iv', c_ubyte * 16),
+    ('buf', c_ubyte * 32),
+    ('num', c_int),
+    ('app_data', c_void_p),
+    ('key_len', c_int),
+    ('flags', c_ulong),
+    ('cipher_data', c_void_p),
+    ('final_used', c_int),
+    ('block_mask', c_int),
+    ('final', c_ubyte * 32),
+]
+assert sizeof(evp_cipher_ctx_st) == 140, sizeof(evp_cipher_ctx_st)
+assert alignment(evp_cipher_ctx_st) == 4, alignment(evp_cipher_ctx_st)
+class evp_Encode_Ctx_st(Structure):
+    pass
+evp_Encode_Ctx_st._fields_ = [
+    ('num', c_int),
+    ('length', c_int),
+    ('enc_data', c_ubyte * 80),
+    ('line_num', c_int),
+    ('expect_nl', c_int),
+]
+assert sizeof(evp_Encode_Ctx_st) == 96, sizeof(evp_Encode_Ctx_st)
+assert alignment(evp_Encode_Ctx_st) == 4, alignment(evp_Encode_Ctx_st)
+EVP_ENCODE_CTX = evp_Encode_Ctx_st
+EVP_PBE_KEYGEN = CFUNCTYPE(c_int, POINTER(EVP_CIPHER_CTX), STRING, c_int, POINTER(ASN1_TYPE), POINTER(EVP_CIPHER), POINTER(EVP_MD), c_int)
+class lhash_node_st(Structure):
+    pass
+lhash_node_st._fields_ = [
+    ('data', c_void_p),
+    ('next', POINTER(lhash_node_st)),
+    ('hash', c_ulong),
+]
+assert sizeof(lhash_node_st) == 12, sizeof(lhash_node_st)
+assert alignment(lhash_node_st) == 4, alignment(lhash_node_st)
+LHASH_NODE = lhash_node_st
+LHASH_COMP_FN_TYPE = CFUNCTYPE(c_int, c_void_p, c_void_p)
+LHASH_HASH_FN_TYPE = CFUNCTYPE(c_ulong, c_void_p)
+LHASH_DOALL_FN_TYPE = CFUNCTYPE(None, c_void_p)
+LHASH_DOALL_ARG_FN_TYPE = CFUNCTYPE(None, c_void_p, c_void_p)
+class lhash_st(Structure):
+    pass
+lhash_st._fields_ = [
+    ('b', POINTER(POINTER(LHASH_NODE))),
+    ('comp', LHASH_COMP_FN_TYPE),
+    ('hash', LHASH_HASH_FN_TYPE),
+    ('num_nodes', c_uint),
+    ('num_alloc_nodes', c_uint),
+    ('p', c_uint),
+    ('pmax', c_uint),
+    ('up_load', c_ulong),
+    ('down_load', c_ulong),
+    ('num_items', c_ulong),
+    ('num_expands', c_ulong),
+    ('num_expand_reallocs', c_ulong),
+    ('num_contracts', c_ulong),
+    ('num_contract_reallocs', c_ulong),
+    ('num_hash_calls', c_ulong),
+    ('num_comp_calls', c_ulong),
+    ('num_insert', c_ulong),
+    ('num_replace', c_ulong),
+    ('num_delete', c_ulong),
+    ('num_no_delete', c_ulong),
+    ('num_retrieve', c_ulong),
+    ('num_retrieve_miss', c_ulong),
+    ('num_hash_comps', c_ulong),
+    ('error', c_int),
+]
+assert sizeof(lhash_st) == 96, sizeof(lhash_st)
+assert alignment(lhash_st) == 4, alignment(lhash_st)
+LHASH = lhash_st
+class MD2state_st(Structure):
+    pass
+MD2state_st._fields_ = [
+    ('num', c_int),
+    ('data', c_ubyte * 16),
+    ('cksm', c_uint * 16),
+    ('state', c_uint * 16),
+]
+assert sizeof(MD2state_st) == 148, sizeof(MD2state_st)
+assert alignment(MD2state_st) == 4, alignment(MD2state_st)
+MD2_CTX = MD2state_st
+class MD4state_st(Structure):
+    pass
+MD4state_st._fields_ = [
+    ('A', c_uint),
+    ('B', c_uint),
+    ('C', c_uint),
+    ('D', c_uint),
+    ('Nl', c_uint),
+    ('Nh', c_uint),
+    ('data', c_uint * 16),
+    ('num', c_int),
+]
+assert sizeof(MD4state_st) == 92, sizeof(MD4state_st)
+assert alignment(MD4state_st) == 4, alignment(MD4state_st)
+MD4_CTX = MD4state_st
+class MD5state_st(Structure):
+    pass
+MD5state_st._fields_ = [
+    ('A', c_uint),
+    ('B', c_uint),
+    ('C', c_uint),
+    ('D', c_uint),
+    ('Nl', c_uint),
+    ('Nh', c_uint),
+    ('data', c_uint * 16),
+    ('num', c_int),
+]
+assert sizeof(MD5state_st) == 92, sizeof(MD5state_st)
+assert alignment(MD5state_st) == 4, alignment(MD5state_st)
+MD5_CTX = MD5state_st
+class mdc2_ctx_st(Structure):
+    pass
+mdc2_ctx_st._fields_ = [
+    ('num', c_int),
+    ('data', c_ubyte * 8),
+    ('h', DES_cblock),
+    ('hh', DES_cblock),
+    ('pad_type', c_int),
+]
+assert sizeof(mdc2_ctx_st) == 32, sizeof(mdc2_ctx_st)
+assert alignment(mdc2_ctx_st) == 4, alignment(mdc2_ctx_st)
+MDC2_CTX = mdc2_ctx_st
+class obj_name_st(Structure):
+    pass
+obj_name_st._fields_ = [
+    ('type', c_int),
+    ('alias', c_int),
+    ('name', STRING),
+    ('data', STRING),
+]
+assert sizeof(obj_name_st) == 16, sizeof(obj_name_st)
+assert alignment(obj_name_st) == 4, alignment(obj_name_st)
+OBJ_NAME = obj_name_st
+ASN1_TIME = asn1_string_st
+ASN1_NULL = c_int
+EVP_PKEY = evp_pkey_st
+class x509_st(Structure):
+    pass
+X509 = x509_st
+class X509_algor_st(Structure):
+    pass
+X509_ALGOR = X509_algor_st
+class X509_crl_st(Structure):
+    pass
+X509_CRL = X509_crl_st
+class X509_name_st(Structure):
+    pass
+X509_NAME = X509_name_st
+class x509_store_st(Structure):
+    pass
+X509_STORE = x509_store_st
+class x509_store_ctx_st(Structure):
+    pass
+X509_STORE_CTX = x509_store_ctx_st
+engine_st._fields_ = [
+]
+class PEM_Encode_Seal_st(Structure):
+    pass
+PEM_Encode_Seal_st._fields_ = [
+    ('encode', EVP_ENCODE_CTX),
+    ('md', EVP_MD_CTX),
+    ('cipher', EVP_CIPHER_CTX),
+]
+assert sizeof(PEM_Encode_Seal_st) == 252, sizeof(PEM_Encode_Seal_st)
+assert alignment(PEM_Encode_Seal_st) == 4, alignment(PEM_Encode_Seal_st)
+PEM_ENCODE_SEAL_CTX = PEM_Encode_Seal_st
+class pem_recip_st(Structure):
+    pass
+pem_recip_st._fields_ = [
+    ('name', STRING),
+    ('dn', POINTER(X509_NAME)),
+    ('cipher', c_int),
+    ('key_enc', c_int),
+]
+assert sizeof(pem_recip_st) == 16, sizeof(pem_recip_st)
+assert alignment(pem_recip_st) == 4, alignment(pem_recip_st)
+PEM_USER = pem_recip_st
+class pem_ctx_st(Structure):
+    pass
+class N10pem_ctx_st4DOLLAR_16E(Structure):
+    pass
+N10pem_ctx_st4DOLLAR_16E._fields_ = [
+    ('version', c_int),
+    ('mode', c_int),
+]
+assert sizeof(N10pem_ctx_st4DOLLAR_16E) == 8, sizeof(N10pem_ctx_st4DOLLAR_16E)
+assert alignment(N10pem_ctx_st4DOLLAR_16E) == 4, alignment(N10pem_ctx_st4DOLLAR_16E)
+class N10pem_ctx_st4DOLLAR_17E(Structure):
+    pass
+N10pem_ctx_st4DOLLAR_17E._fields_ = [
+    ('cipher', c_int),
+]
+assert sizeof(N10pem_ctx_st4DOLLAR_17E) == 4, sizeof(N10pem_ctx_st4DOLLAR_17E)
+assert alignment(N10pem_ctx_st4DOLLAR_17E) == 4, alignment(N10pem_ctx_st4DOLLAR_17E)
+pem_ctx_st._fields_ = [
+    ('type', c_int),
+    ('proc_type', N10pem_ctx_st4DOLLAR_16E),
+    ('domain', STRING),
+    ('DEK_info', N10pem_ctx_st4DOLLAR_17E),
+    ('originator', POINTER(PEM_USER)),
+    ('num_recipient', c_int),
+    ('recipient', POINTER(POINTER(PEM_USER))),
+    ('x509_chain', POINTER(STACK)),
+    ('md', POINTER(EVP_MD)),
+    ('md_enc', c_int),
+    ('md_len', c_int),
+    ('md_data', STRING),
+    ('dec', POINTER(EVP_CIPHER)),
+    ('key_len', c_int),
+    ('key', POINTER(c_ubyte)),
+    ('data_enc', c_int),
+    ('data_len', c_int),
+    ('data', POINTER(c_ubyte)),
+]
+assert sizeof(pem_ctx_st) == 76, sizeof(pem_ctx_st)
+assert alignment(pem_ctx_st) == 4, alignment(pem_ctx_st)
+PEM_CTX = pem_ctx_st
+pem_password_cb = CFUNCTYPE(c_int, STRING, c_int, c_int, c_void_p)
+class pkcs7_issuer_and_serial_st(Structure):
+    pass
+pkcs7_issuer_and_serial_st._fields_ = [
+    ('issuer', POINTER(X509_NAME)),
+    ('serial', POINTER(ASN1_INTEGER)),
+]
+assert sizeof(pkcs7_issuer_and_serial_st) == 8, sizeof(pkcs7_issuer_and_serial_st)
+assert alignment(pkcs7_issuer_and_serial_st) == 4, alignment(pkcs7_issuer_and_serial_st)
+PKCS7_ISSUER_AND_SERIAL = pkcs7_issuer_and_serial_st
+class pkcs7_signer_info_st(Structure):
+    pass
+pkcs7_signer_info_st._fields_ = [
+    ('version', POINTER(ASN1_INTEGER)),
+    ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)),
+    ('digest_alg', POINTER(X509_ALGOR)),
+    ('auth_attr', POINTER(STACK)),
+    ('digest_enc_alg', POINTER(X509_ALGOR)),
+    ('enc_digest', POINTER(ASN1_OCTET_STRING)),
+    ('unauth_attr', POINTER(STACK)),
+    ('pkey', POINTER(EVP_PKEY)),
+]
+assert sizeof(pkcs7_signer_info_st) == 32, sizeof(pkcs7_signer_info_st)
+assert alignment(pkcs7_signer_info_st) == 4, alignment(pkcs7_signer_info_st)
+PKCS7_SIGNER_INFO = pkcs7_signer_info_st
+class pkcs7_recip_info_st(Structure):
+    pass
+pkcs7_recip_info_st._fields_ = [
+    ('version', POINTER(ASN1_INTEGER)),
+    ('issuer_and_serial', POINTER(PKCS7_ISSUER_AND_SERIAL)),
+    ('key_enc_algor', POINTER(X509_ALGOR)),
+    ('enc_key', POINTER(ASN1_OCTET_STRING)),
+    ('cert', POINTER(X509)),
+]
+assert sizeof(pkcs7_recip_info_st) == 20, sizeof(pkcs7_recip_info_st)
+assert alignment(pkcs7_recip_info_st) == 4, alignment(pkcs7_recip_info_st)
+PKCS7_RECIP_INFO = pkcs7_recip_info_st
+class pkcs7_signed_st(Structure):
+    pass
+class pkcs7_st(Structure):
+    pass
+pkcs7_signed_st._fields_ = [
+    ('version', POINTER(ASN1_INTEGER)),
+    ('md_algs', POINTER(STACK)),
+    ('cert', POINTER(STACK)),
+    ('crl', POINTER(STACK)),
+    ('signer_info', POINTER(STACK)),
+    ('contents', POINTER(pkcs7_st)),
+]
+assert sizeof(pkcs7_signed_st) == 24, sizeof(pkcs7_signed_st)
+assert alignment(pkcs7_signed_st) == 4, alignment(pkcs7_signed_st)
+PKCS7_SIGNED = pkcs7_signed_st
+class pkcs7_enc_content_st(Structure):
+    pass
+pkcs7_enc_content_st._fields_ = [
+    ('content_type', POINTER(ASN1_OBJECT)),
+    ('algorithm', POINTER(X509_ALGOR)),
+    ('enc_data', POINTER(ASN1_OCTET_STRING)),
+    ('cipher', POINTER(EVP_CIPHER)),
+]
+assert sizeof(pkcs7_enc_content_st) == 16, sizeof(pkcs7_enc_content_st)
+assert alignment(pkcs7_enc_content_st) == 4, alignment(pkcs7_enc_content_st)
+PKCS7_ENC_CONTENT = pkcs7_enc_content_st
+class pkcs7_enveloped_st(Structure):
+    pass
+pkcs7_enveloped_st._fields_ = [
+    ('version', POINTER(ASN1_INTEGER)),
+    ('recipientinfo', POINTER(STACK)),
+    ('enc_data', POINTER(PKCS7_ENC_CONTENT)),
+]
+assert sizeof(pkcs7_enveloped_st) == 12, sizeof(pkcs7_enveloped_st)
+assert alignment(pkcs7_enveloped_st) == 4, alignment(pkcs7_enveloped_st)
+PKCS7_ENVELOPE = pkcs7_enveloped_st
+class pkcs7_signedandenveloped_st(Structure):
+    pass
+pkcs7_signedandenveloped_st._fields_ = [
+    ('version', POINTER(ASN1_INTEGER)),
+    ('md_algs', POINTER(STACK)),
+    ('cert', POINTER(STACK)),
+    ('crl', POINTER(STACK)),
+    ('signer_info', POINTER(STACK)),
+    ('enc_data', POINTER(PKCS7_ENC_CONTENT)),
+    ('recipientinfo', POINTER(STACK)),
+]
+assert sizeof(pkcs7_signedandenveloped_st) == 28, sizeof(pkcs7_signedandenveloped_st)
+assert alignment(pkcs7_signedandenveloped_st) == 4, alignment(pkcs7_signedandenveloped_st)
+PKCS7_SIGN_ENVELOPE = pkcs7_signedandenveloped_st
+class pkcs7_digest_st(Structure):
+    pass
+pkcs7_digest_st._fields_ = [
+    ('version', POINTER(ASN1_INTEGER)),
+    ('md', POINTER(X509_ALGOR)),
+    ('contents', POINTER(pkcs7_st)),
+    ('digest', POINTER(ASN1_OCTET_STRING)),
+]
+assert sizeof(pkcs7_digest_st) == 16, sizeof(pkcs7_digest_st)
+assert alignment(pkcs7_digest_st) == 4, alignment(pkcs7_digest_st)
+PKCS7_DIGEST = pkcs7_digest_st
+class pkcs7_encrypted_st(Structure):
+    pass
+pkcs7_encrypted_st._fields_ = [
+    ('version', POINTER(ASN1_INTEGER)),
+    ('enc_data', POINTER(PKCS7_ENC_CONTENT)),
+]
+assert sizeof(pkcs7_encrypted_st) == 8, sizeof(pkcs7_encrypted_st)
+assert alignment(pkcs7_encrypted_st) == 4, alignment(pkcs7_encrypted_st)
+PKCS7_ENCRYPT = pkcs7_encrypted_st
+class N8pkcs7_st4DOLLAR_15E(Union):
+    pass
+N8pkcs7_st4DOLLAR_15E._fields_ = [
+    ('ptr', STRING),
+    ('data', POINTER(ASN1_OCTET_STRING)),
+    ('sign', POINTER(PKCS7_SIGNED)),
+    ('enveloped', POINTER(PKCS7_ENVELOPE)),
+    ('signed_and_enveloped', POINTER(PKCS7_SIGN_ENVELOPE)),
+    ('digest', POINTER(PKCS7_DIGEST)),
+    ('encrypted', POINTER(PKCS7_ENCRYPT)),
+    ('other', POINTER(ASN1_TYPE)),
+]
+assert sizeof(N8pkcs7_st4DOLLAR_15E) == 4, sizeof(N8pkcs7_st4DOLLAR_15E)
+assert alignment(N8pkcs7_st4DOLLAR_15E) == 4, alignment(N8pkcs7_st4DOLLAR_15E)
+pkcs7_st._fields_ = [
+    ('asn1', POINTER(c_ubyte)),
+    ('length', c_long),
+    ('state', c_int),
+    ('detached', c_int),
+    ('type', POINTER(ASN1_OBJECT)),
+    ('d', N8pkcs7_st4DOLLAR_15E),
+]
+assert sizeof(pkcs7_st) == 24, sizeof(pkcs7_st)
+assert alignment(pkcs7_st) == 4, alignment(pkcs7_st)
+PKCS7 = pkcs7_st
+class rc2_key_st(Structure):
+    pass
+rc2_key_st._fields_ = [
+    ('data', c_uint * 64),
+]
+assert sizeof(rc2_key_st) == 256, sizeof(rc2_key_st)
+assert alignment(rc2_key_st) == 4, alignment(rc2_key_st)
+RC2_KEY = rc2_key_st
+class rc4_key_st(Structure):
+    pass
+rc4_key_st._fields_ = [
+    ('x', c_ubyte),
+    ('y', c_ubyte),
+    ('data', c_ubyte * 256),
+]
+assert sizeof(rc4_key_st) == 258, sizeof(rc4_key_st)
+assert alignment(rc4_key_st) == 1, alignment(rc4_key_st)
+RC4_KEY = rc4_key_st
+class rc5_key_st(Structure):
+    pass
+rc5_key_st._fields_ = [
+    ('rounds', c_int),
+    ('data', c_ulong * 34),
+]
+assert sizeof(rc5_key_st) == 140, sizeof(rc5_key_st)
+assert alignment(rc5_key_st) == 4, alignment(rc5_key_st)
+RC5_32_KEY = rc5_key_st
+class RIPEMD160state_st(Structure):
+    pass
+RIPEMD160state_st._fields_ = [
+    ('A', c_uint),
+    ('B', c_uint),
+    ('C', c_uint),
+    ('D', c_uint),
+    ('E', c_uint),
+    ('Nl', c_uint),
+    ('Nh', c_uint),
+    ('data', c_uint * 16),
+    ('num', c_int),
+]
+assert sizeof(RIPEMD160state_st) == 96, sizeof(RIPEMD160state_st)
+assert alignment(RIPEMD160state_st) == 4, alignment(RIPEMD160state_st)
+RIPEMD160_CTX = RIPEMD160state_st
+RSA = rsa_st
+class rsa_meth_st(Structure):
+    pass
+rsa_meth_st._fields_ = [
+    ('name', STRING),
+    ('rsa_pub_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)),
+    ('rsa_pub_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)),
+    ('rsa_priv_enc', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)),
+    ('rsa_priv_dec', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), POINTER(c_ubyte), POINTER(RSA), c_int)),
+    ('rsa_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(RSA))),
+    ('bn_mod_exp', CFUNCTYPE(c_int, POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BIGNUM), POINTER(BN_CTX), POINTER(BN_MONT_CTX))),
+    ('init', CFUNCTYPE(c_int, POINTER(RSA))),
+    ('finish', CFUNCTYPE(c_int, POINTER(RSA))),
+    ('flags', c_int),
+    ('app_data', STRING),
+    ('rsa_sign', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), POINTER(c_uint), POINTER(RSA))),
+    ('rsa_verify', CFUNCTYPE(c_int, c_int, POINTER(c_ubyte), c_uint, POINTER(c_ubyte), c_uint, POINTER(RSA))),
+]
+assert sizeof(rsa_meth_st) == 52, sizeof(rsa_meth_st)
+assert alignment(rsa_meth_st) == 4, alignment(rsa_meth_st)
+RSA_METHOD = rsa_meth_st
+rsa_st._fields_ = [
+    ('pad', c_int),
+    ('version', c_long),
+    ('meth', POINTER(RSA_METHOD)),
+    ('engine', POINTER(ENGINE)),
+    ('n', POINTER(BIGNUM)),
+    ('e', POINTER(BIGNUM)),
+    ('d', POINTER(BIGNUM)),
+    ('p', POINTER(BIGNUM)),
+    ('q', POINTER(BIGNUM)),
+    ('dmp1', POINTER(BIGNUM)),
+    ('dmq1', POINTER(BIGNUM)),
+    ('iqmp', POINTER(BIGNUM)),
+    ('ex_data', CRYPTO_EX_DATA),
+    ('references', c_int),
+    ('flags', c_int),
+    ('_method_mod_n', POINTER(BN_MONT_CTX)),
+    ('_method_mod_p', POINTER(BN_MONT_CTX)),
+    ('_method_mod_q', POINTER(BN_MONT_CTX)),
+    ('bignum_data', STRING),
+    ('blinding', POINTER(BN_BLINDING)),
+]
+assert sizeof(rsa_st) == 84, sizeof(rsa_st)
+assert alignment(rsa_st) == 4, alignment(rsa_st)
+openssl_fptr = CFUNCTYPE(None)
+class SHAstate_st(Structure):
+    pass
+SHAstate_st._fields_ = [
+    ('h0', c_uint),
+    ('h1', c_uint),
+    ('h2', c_uint),
+    ('h3', c_uint),
+    ('h4', c_uint),
+    ('Nl', c_uint),
+    ('Nh', c_uint),
+    ('data', c_uint * 16),
+    ('num', c_int),
+]
+assert sizeof(SHAstate_st) == 96, sizeof(SHAstate_st)
+assert alignment(SHAstate_st) == 4, alignment(SHAstate_st)
+SHA_CTX = SHAstate_st
+class ssl_st(Structure):
+    pass
+ssl_crock_st = POINTER(ssl_st)
+class ssl_cipher_st(Structure):
+    pass
+ssl_cipher_st._fields_ = [
+    ('valid', c_int),
+    ('name', STRING),
+    ('id', c_ulong),
+    ('algorithms', c_ulong),
+    ('algo_strength', c_ulong),
+    ('algorithm2', c_ulong),
+    ('strength_bits', c_int),
+    ('alg_bits', c_int),
+    ('mask', c_ulong),
+    ('mask_strength', c_ulong),
+]
+assert sizeof(ssl_cipher_st) == 40, sizeof(ssl_cipher_st)
+assert alignment(ssl_cipher_st) == 4, alignment(ssl_cipher_st)
+SSL_CIPHER = ssl_cipher_st
+SSL = ssl_st
+class ssl_ctx_st(Structure):
+    pass
+SSL_CTX = ssl_ctx_st
+class ssl_method_st(Structure):
+    pass
+class ssl3_enc_method(Structure):
+    pass
+ssl_method_st._fields_ = [
+    ('version', c_int),
+    ('ssl_new', CFUNCTYPE(c_int, POINTER(SSL))),
+    ('ssl_clear', CFUNCTYPE(None, POINTER(SSL))),
+    ('ssl_free', CFUNCTYPE(None, POINTER(SSL))),
+    ('ssl_accept', CFUNCTYPE(c_int, POINTER(SSL))),
+    ('ssl_connect', CFUNCTYPE(c_int, POINTER(SSL))),
+    ('ssl_read', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)),
+    ('ssl_peek', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)),
+    ('ssl_write', CFUNCTYPE(c_int, POINTER(SSL), c_void_p, c_int)),
+    ('ssl_shutdown', CFUNCTYPE(c_int, POINTER(SSL))),
+    ('ssl_renegotiate', CFUNCTYPE(c_int, POINTER(SSL))),
+    ('ssl_renegotiate_check', CFUNCTYPE(c_int, POINTER(SSL))),
+    ('ssl_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, c_long, c_void_p)),
+    ('ssl_ctx_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, c_long, c_void_p)),
+    ('get_cipher_by_char', CFUNCTYPE(POINTER(SSL_CIPHER), POINTER(c_ubyte))),
+    ('put_cipher_by_char', CFUNCTYPE(c_int, POINTER(SSL_CIPHER), POINTER(c_ubyte))),
+    ('ssl_pending', CFUNCTYPE(c_int, POINTER(SSL))),
+    ('num_ciphers', CFUNCTYPE(c_int)),
+    ('get_cipher', CFUNCTYPE(POINTER(SSL_CIPHER), c_uint)),
+    ('get_ssl_method', CFUNCTYPE(POINTER(ssl_method_st), c_int)),
+    ('get_timeout', CFUNCTYPE(c_long)),
+    ('ssl3_enc', POINTER(ssl3_enc_method)),
+    ('ssl_version', CFUNCTYPE(c_int)),
+    ('ssl_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL), c_int, CFUNCTYPE(None))),
+    ('ssl_ctx_callback_ctrl', CFUNCTYPE(c_long, POINTER(SSL_CTX), c_int, CFUNCTYPE(None))),
+]
+assert sizeof(ssl_method_st) == 100, sizeof(ssl_method_st)
+assert alignment(ssl_method_st) == 4, alignment(ssl_method_st)
+ssl3_enc_method._fields_ = [
+]
+SSL_METHOD = ssl_method_st
+class ssl_session_st(Structure):
+    pass
+class sess_cert_st(Structure):
+    pass
+ssl_session_st._fields_ = [
+    ('ssl_version', c_int),
+    ('key_arg_length', c_uint),
+    ('key_arg', c_ubyte * 8),
+    ('master_key_length', c_int),
+    ('master_key', c_ubyte * 48),
+    ('session_id_length', c_uint),
+    ('session_id', c_ubyte * 32),
+    ('sid_ctx_length', c_uint),
+    ('sid_ctx', c_ubyte * 32),
+    ('not_resumable', c_int),
+    ('sess_cert', POINTER(sess_cert_st)),
+    ('peer', POINTER(X509)),
+    ('verify_result', c_long),
+    ('references', c_int),
+    ('timeout', c_long),
+    ('time', c_long),
+    ('compress_meth', c_int),
+    ('cipher', POINTER(SSL_CIPHER)),
+    ('cipher_id', c_ulong),
+    ('ciphers', POINTER(STACK)),
+    ('ex_data', CRYPTO_EX_DATA),
+    ('prev', POINTER(ssl_session_st)),
+    ('next', POINTER(ssl_session_st)),
+]
+assert sizeof(ssl_session_st) == 200, sizeof(ssl_session_st)
+assert alignment(ssl_session_st) == 4, alignment(ssl_session_st)
+sess_cert_st._fields_ = [
+]
+SSL_SESSION = ssl_session_st
+GEN_SESSION_CB = CFUNCTYPE(c_int, POINTER(SSL), POINTER(c_ubyte), POINTER(c_uint))
+class ssl_comp_st(Structure):
+    pass
+ssl_comp_st._fields_ = [
+    ('id', c_int),
+    ('name', STRING),
+    ('method', POINTER(COMP_METHOD)),
+]
+assert sizeof(ssl_comp_st) == 12, sizeof(ssl_comp_st)
+assert alignment(ssl_comp_st) == 4, alignment(ssl_comp_st)
+SSL_COMP = ssl_comp_st
+class N10ssl_ctx_st4DOLLAR_18E(Structure):
+    pass
+N10ssl_ctx_st4DOLLAR_18E._fields_ = [
+    ('sess_connect', c_int),
+    ('sess_connect_renegotiate', c_int),
+    ('sess_connect_good', c_int),
+    ('sess_accept', c_int),
+    ('sess_accept_renegotiate', c_int),
+    ('sess_accept_good', c_int),
+    ('sess_miss', c_int),
+    ('sess_timeout', c_int),
+    ('sess_cache_full', c_int),
+    ('sess_hit', c_int),
+    ('sess_cb_hit', c_int),
+]
+assert sizeof(N10ssl_ctx_st4DOLLAR_18E) == 44, sizeof(N10ssl_ctx_st4DOLLAR_18E)
+assert alignment(N10ssl_ctx_st4DOLLAR_18E) == 4, alignment(N10ssl_ctx_st4DOLLAR_18E)
+class cert_st(Structure):
+    pass
+ssl_ctx_st._fields_ = [
+    ('method', POINTER(SSL_METHOD)),
+    ('cipher_list', POINTER(STACK)),
+    ('cipher_list_by_id', POINTER(STACK)),
+    ('cert_store', POINTER(x509_store_st)),
+    ('sessions', POINTER(lhash_st)),
+    ('session_cache_size', c_ulong),
+    ('session_cache_head', POINTER(ssl_session_st)),
+    ('session_cache_tail', POINTER(ssl_session_st)),
+    ('session_cache_mode', c_int),
+    ('session_timeout', c_long),
+    ('new_session_cb', CFUNCTYPE(c_int, POINTER(ssl_st), POINTER(SSL_SESSION))),
+    ('remove_session_cb', CFUNCTYPE(None, POINTER(ssl_ctx_st), POINTER(SSL_SESSION))),
+    ('get_session_cb', CFUNCTYPE(POINTER(SSL_SESSION), POINTER(ssl_st), POINTER(c_ubyte), c_int, POINTER(c_int))),
+    ('stats', N10ssl_ctx_st4DOLLAR_18E),
+    ('references', c_int),
+    ('app_verify_callback', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), c_void_p)),
+    ('app_verify_arg', c_void_p),
+    ('default_passwd_callback', POINTER(pem_password_cb)),
+    ('default_passwd_callback_userdata', c_void_p),
+    ('client_cert_cb', CFUNCTYPE(c_int, POINTER(SSL), POINTER(POINTER(X509)), POINTER(POINTER(EVP_PKEY)))),
+    ('ex_data', CRYPTO_EX_DATA),
+    ('rsa_md5', POINTER(EVP_MD)),
+    ('md5', POINTER(EVP_MD)),
+    ('sha1', POINTER(EVP_MD)),
+    ('extra_certs', POINTER(STACK)),
+    ('comp_methods', POINTER(STACK)),
+    ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)),
+    ('client_CA', POINTER(STACK)),
+    ('options', c_ulong),
+    ('mode', c_ulong),
+    ('max_cert_list', c_long),
+    ('cert', POINTER(cert_st)),
+    ('read_ahead', c_int),
+    ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)),
+    ('msg_callback_arg', c_void_p),
+    ('verify_mode', c_int),
+    ('verify_depth', c_int),
+    ('sid_ctx_length', c_uint),
+    ('sid_ctx', c_ubyte * 32),
+    ('default_verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))),
+    ('generate_session_id', GEN_SESSION_CB),
+    ('purpose', c_int),
+    ('trust', c_int),
+    ('quiet_shutdown', c_int),
+]
+assert sizeof(ssl_ctx_st) == 248, sizeof(ssl_ctx_st)
+assert alignment(ssl_ctx_st) == 4, alignment(ssl_ctx_st)
+cert_st._fields_ = [
+]
+class ssl2_state_st(Structure):
+    pass
+class ssl3_state_st(Structure):
+    pass
+ssl_st._fields_ = [
+    ('version', c_int),
+    ('type', c_int),
+    ('method', POINTER(SSL_METHOD)),
+    ('rbio', POINTER(BIO)),
+    ('wbio', POINTER(BIO)),
+    ('bbio', POINTER(BIO)),
+    ('rwstate', c_int),
+    ('in_handshake', c_int),
+    ('handshake_func', CFUNCTYPE(c_int)),
+    ('server', c_int),
+    ('new_session', c_int),
+    ('quiet_shutdown', c_int),
+    ('shutdown', c_int),
+    ('state', c_int),
+    ('rstate', c_int),
+    ('init_buf', POINTER(BUF_MEM)),
+    ('init_msg', c_void_p),
+    ('init_num', c_int),
+    ('init_off', c_int),
+    ('packet', POINTER(c_ubyte)),
+    ('packet_length', c_uint),
+    ('s2', POINTER(ssl2_state_st)),
+    ('s3', POINTER(ssl3_state_st)),
+    ('read_ahead', c_int),
+    ('msg_callback', CFUNCTYPE(None, c_int, c_int, c_int, c_void_p, c_ulong, POINTER(SSL), c_void_p)),
+    ('msg_callback_arg', c_void_p),
+    ('hit', c_int),
+    ('purpose', c_int),
+    ('trust', c_int),
+    ('cipher_list', POINTER(STACK)),
+    ('cipher_list_by_id', POINTER(STACK)),
+    ('enc_read_ctx', POINTER(EVP_CIPHER_CTX)),
+    ('read_hash', POINTER(EVP_MD)),
+    ('expand', POINTER(COMP_CTX)),
+    ('enc_write_ctx', POINTER(EVP_CIPHER_CTX)),
+    ('write_hash', POINTER(EVP_MD)),
+    ('compress', POINTER(COMP_CTX)),
+    ('cert', POINTER(cert_st)),
+    ('sid_ctx_length', c_uint),
+    ('sid_ctx', c_ubyte * 32),
+    ('session', POINTER(SSL_SESSION)),
+    ('generate_session_id', GEN_SESSION_CB),
+    ('verify_mode', c_int),
+    ('verify_depth', c_int),
+    ('verify_callback', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))),
+    ('info_callback', CFUNCTYPE(None, POINTER(SSL), c_int, c_int)),
+    ('error', c_int),
+    ('error_code', c_int),
+    ('ctx', POINTER(SSL_CTX)),
+    ('debug', c_int),
+    ('verify_result', c_long),
+    ('ex_data', CRYPTO_EX_DATA),
+    ('client_CA', POINTER(STACK)),
+    ('references', c_int),
+    ('options', c_ulong),
+    ('mode', c_ulong),
+    ('max_cert_list', c_long),
+    ('first_packet', c_int),
+    ('client_version', c_int),
+]
+assert sizeof(ssl_st) == 268, sizeof(ssl_st)
+assert alignment(ssl_st) == 4, alignment(ssl_st)
+class N13ssl2_state_st4DOLLAR_19E(Structure):
+    pass
+N13ssl2_state_st4DOLLAR_19E._fields_ = [
+    ('conn_id_length', c_uint),
+    ('cert_type', c_uint),
+    ('cert_length', c_uint),
+    ('csl', c_uint),
+    ('clear', c_uint),
+    ('enc', c_uint),
+    ('ccl', c_ubyte * 32),
+    ('cipher_spec_length', c_uint),
+    ('session_id_length', c_uint),
+    ('clen', c_uint),
+    ('rlen', c_uint),
+]
+assert sizeof(N13ssl2_state_st4DOLLAR_19E) == 72, sizeof(N13ssl2_state_st4DOLLAR_19E)
+assert alignment(N13ssl2_state_st4DOLLAR_19E) == 4, alignment(N13ssl2_state_st4DOLLAR_19E)
+ssl2_state_st._fields_ = [
+    ('three_byte_header', c_int),
+    ('clear_text', c_int),
+    ('escape', c_int),
+    ('ssl2_rollback', c_int),
+    ('wnum', c_uint),
+    ('wpend_tot', c_int),
+    ('wpend_buf', POINTER(c_ubyte)),
+    ('wpend_off', c_int),
+    ('wpend_len', c_int),
+    ('wpend_ret', c_int),
+    ('rbuf_left', c_int),
+    ('rbuf_offs', c_int),
+    ('rbuf', POINTER(c_ubyte)),
+    ('wbuf', POINTER(c_ubyte)),
+    ('write_ptr', POINTER(c_ubyte)),
+    ('padding', c_uint),
+    ('rlength', c_uint),
+    ('ract_data_length', c_int),
+    ('wlength', c_uint),
+    ('wact_data_length', c_int),
+    ('ract_data', POINTER(c_ubyte)),
+    ('wact_data', POINTER(c_ubyte)),
+    ('mac_data', POINTER(c_ubyte)),
+    ('read_key', POINTER(c_ubyte)),
+    ('write_key', POINTER(c_ubyte)),
+    ('challenge_length', c_uint),
+    ('challenge', c_ubyte * 32),
+    ('conn_id_length', c_uint),
+    ('conn_id', c_ubyte * 16),
+    ('key_material_length', c_uint),
+    ('key_material', c_ubyte * 48),
+    ('read_sequence', c_ulong),
+    ('write_sequence', c_ulong),
+    ('tmp', N13ssl2_state_st4DOLLAR_19E),
+]
+assert sizeof(ssl2_state_st) == 288, sizeof(ssl2_state_st)
+assert alignment(ssl2_state_st) == 4, alignment(ssl2_state_st)
+SSL2_STATE = ssl2_state_st
+class ssl3_record_st(Structure):
+    pass
+ssl3_record_st._fields_ = [
+    ('type', c_int),
+    ('length', c_uint),
+    ('off', c_uint),
+    ('data', POINTER(c_ubyte)),
+    ('input', POINTER(c_ubyte)),
+    ('comp', POINTER(c_ubyte)),
+]
+assert sizeof(ssl3_record_st) == 24, sizeof(ssl3_record_st)
+assert alignment(ssl3_record_st) == 4, alignment(ssl3_record_st)
+SSL3_RECORD = ssl3_record_st
+class ssl3_buffer_st(Structure):
+    pass
+size_t = __darwin_size_t
+ssl3_buffer_st._fields_ = [
+    ('buf', POINTER(c_ubyte)),
+    ('len', size_t),
+    ('offset', c_int),
+    ('left', c_int),
+]
+assert sizeof(ssl3_buffer_st) == 16, sizeof(ssl3_buffer_st)
+assert alignment(ssl3_buffer_st) == 4, alignment(ssl3_buffer_st)
+SSL3_BUFFER = ssl3_buffer_st
+class N13ssl3_state_st4DOLLAR_20E(Structure):
+    pass
+N13ssl3_state_st4DOLLAR_20E._fields_ = [
+    ('cert_verify_md', c_ubyte * 72),
+    ('finish_md', c_ubyte * 72),
+    ('finish_md_len', c_int),
+    ('peer_finish_md', c_ubyte * 72),
+    ('peer_finish_md_len', c_int),
+    ('message_size', c_ulong),
+    ('message_type', c_int),
+    ('new_cipher', POINTER(SSL_CIPHER)),
+    ('dh', POINTER(DH)),
+    ('next_state', c_int),
+    ('reuse_message', c_int),
+    ('cert_req', c_int),
+    ('ctype_num', c_int),
+    ('ctype', c_char * 7),
+    ('ca_names', POINTER(STACK)),
+    ('use_rsa_tmp', c_int),
+    ('key_block_length', c_int),
+    ('key_block', POINTER(c_ubyte)),
+    ('new_sym_enc', POINTER(EVP_CIPHER)),
+    ('new_hash', POINTER(EVP_MD)),
+    ('new_compression', POINTER(SSL_COMP)),
+    ('cert_request', c_int),
+]
+assert sizeof(N13ssl3_state_st4DOLLAR_20E) == 296, sizeof(N13ssl3_state_st4DOLLAR_20E)
+assert alignment(N13ssl3_state_st4DOLLAR_20E) == 4, alignment(N13ssl3_state_st4DOLLAR_20E)
+ssl3_state_st._fields_ = [
+    ('flags', c_long),
+    ('delay_buf_pop_ret', c_int),
+    ('read_sequence', c_ubyte * 8),
+    ('read_mac_secret', c_ubyte * 36),
+    ('write_sequence', c_ubyte * 8),
+    ('write_mac_secret', c_ubyte * 36),
+    ('server_random', c_ubyte * 32),
+    ('client_random', c_ubyte * 32),
+    ('need_empty_fragments', c_int),
+    ('empty_fragment_done', c_int),
+    ('rbuf', SSL3_BUFFER),
+    ('wbuf', SSL3_BUFFER),
+    ('rrec', SSL3_RECORD),
+    ('wrec', SSL3_RECORD),
+    ('alert_fragment', c_ubyte * 2),
+    ('alert_fragment_len', c_uint),
+    ('handshake_fragment', c_ubyte * 4),
+    ('handshake_fragment_len', c_uint),
+    ('wnum', c_uint),
+    ('wpend_tot', c_int),
+    ('wpend_type', c_int),
+    ('wpend_ret', c_int),
+    ('wpend_buf', POINTER(c_ubyte)),
+    ('finish_dgst1', EVP_MD_CTX),
+    ('finish_dgst2', EVP_MD_CTX),
+    ('change_cipher_spec', c_int),
+    ('warn_alert', c_int),
+    ('fatal_alert', c_int),
+    ('alert_dispatch', c_int),
+    ('send_alert', c_ubyte * 2),
+    ('renegotiate', c_int),
+    ('total_renegotiations', c_int),
+    ('num_renegotiations', c_int),
+    ('in_read_app_data', c_int),
+    ('tmp', N13ssl3_state_st4DOLLAR_20E),
+]
+assert sizeof(ssl3_state_st) == 648, sizeof(ssl3_state_st)
+assert alignment(ssl3_state_st) == 4, alignment(ssl3_state_st)
+SSL3_STATE = ssl3_state_st
+stack_st._fields_ = [
+    ('num', c_int),
+    ('data', POINTER(STRING)),
+    ('sorted', c_int),
+    ('num_alloc', c_int),
+    ('comp', CFUNCTYPE(c_int, POINTER(STRING), POINTER(STRING))),
+]
+assert sizeof(stack_st) == 20, sizeof(stack_st)
+assert alignment(stack_st) == 4, alignment(stack_st)
+class ui_st(Structure):
+    pass
+ui_st._fields_ = [
+]
+UI = ui_st
+class ui_method_st(Structure):
+    pass
+ui_method_st._fields_ = [
+]
+UI_METHOD = ui_method_st
+class ui_string_st(Structure):
+    pass
+ui_string_st._fields_ = [
+]
+UI_STRING = ui_string_st
+
+# values for enumeration 'UI_string_types'
+UI_string_types = c_int # enum
+class X509_objects_st(Structure):
+    pass
+X509_objects_st._fields_ = [
+    ('nid', c_int),
+    ('a2i', CFUNCTYPE(c_int)),
+    ('i2a', CFUNCTYPE(c_int)),
+]
+assert sizeof(X509_objects_st) == 12, sizeof(X509_objects_st)
+assert alignment(X509_objects_st) == 4, alignment(X509_objects_st)
+X509_OBJECTS = X509_objects_st
+X509_algor_st._fields_ = [
+    ('algorithm', POINTER(ASN1_OBJECT)),
+    ('parameter', POINTER(ASN1_TYPE)),
+]
+assert sizeof(X509_algor_st) == 8, sizeof(X509_algor_st)
+assert alignment(X509_algor_st) == 4, alignment(X509_algor_st)
+class X509_val_st(Structure):
+    pass
+X509_val_st._fields_ = [
+    ('notBefore', POINTER(ASN1_TIME)),
+    ('notAfter', POINTER(ASN1_TIME)),
+]
+assert sizeof(X509_val_st) == 8, sizeof(X509_val_st)
+assert alignment(X509_val_st) == 4, alignment(X509_val_st)
+X509_VAL = X509_val_st
+class X509_pubkey_st(Structure):
+    pass
+X509_pubkey_st._fields_ = [
+    ('algor', POINTER(X509_ALGOR)),
+    ('public_key', POINTER(ASN1_BIT_STRING)),
+    ('pkey', POINTER(EVP_PKEY)),
+]
+assert sizeof(X509_pubkey_st) == 12, sizeof(X509_pubkey_st)
+assert alignment(X509_pubkey_st) == 4, alignment(X509_pubkey_st)
+X509_PUBKEY = X509_pubkey_st
+class X509_sig_st(Structure):
+    pass
+X509_sig_st._fields_ = [
+    ('algor', POINTER(X509_ALGOR)),
+    ('digest', POINTER(ASN1_OCTET_STRING)),
+]
+assert sizeof(X509_sig_st) == 8, sizeof(X509_sig_st)
+assert alignment(X509_sig_st) == 4, alignment(X509_sig_st)
+X509_SIG = X509_sig_st
+class X509_name_entry_st(Structure):
+    pass
+X509_name_entry_st._fields_ = [
+    ('object', POINTER(ASN1_OBJECT)),
+    ('value', POINTER(ASN1_STRING)),
+    ('set', c_int),
+    ('size', c_int),
+]
+assert sizeof(X509_name_entry_st) == 16, sizeof(X509_name_entry_st)
+assert alignment(X509_name_entry_st) == 4, alignment(X509_name_entry_st)
+X509_NAME_ENTRY = X509_name_entry_st
+X509_name_st._fields_ = [
+    ('entries', POINTER(STACK)),
+    ('modified', c_int),
+    ('bytes', POINTER(BUF_MEM)),
+    ('hash', c_ulong),
+]
+assert sizeof(X509_name_st) == 16, sizeof(X509_name_st)
+assert alignment(X509_name_st) == 4, alignment(X509_name_st)
+class X509_extension_st(Structure):
+    pass
+X509_extension_st._fields_ = [
+    ('object', POINTER(ASN1_OBJECT)),
+    ('critical', ASN1_BOOLEAN),
+    ('value', POINTER(ASN1_OCTET_STRING)),
+]
+assert sizeof(X509_extension_st) == 12, sizeof(X509_extension_st)
+assert alignment(X509_extension_st) == 4, alignment(X509_extension_st)
+X509_EXTENSION = X509_extension_st
+class x509_attributes_st(Structure):
+    pass
+class N18x509_attributes_st4DOLLAR_13E(Union):
+    pass
+N18x509_attributes_st4DOLLAR_13E._fields_ = [
+    ('ptr', STRING),
+    ('set', POINTER(STACK)),
+    ('single', POINTER(ASN1_TYPE)),
+]
+assert sizeof(N18x509_attributes_st4DOLLAR_13E) == 4, sizeof(N18x509_attributes_st4DOLLAR_13E)
+assert alignment(N18x509_attributes_st4DOLLAR_13E) == 4, alignment(N18x509_attributes_st4DOLLAR_13E)
+x509_attributes_st._fields_ = [
+    ('object', POINTER(ASN1_OBJECT)),
+    ('single', c_int),
+    ('value', N18x509_attributes_st4DOLLAR_13E),
+]
+assert sizeof(x509_attributes_st) == 12, sizeof(x509_attributes_st)
+assert alignment(x509_attributes_st) == 4, alignment(x509_attributes_st)
+X509_ATTRIBUTE = x509_attributes_st
+class X509_req_info_st(Structure):
+    pass
+X509_req_info_st._fields_ = [
+    ('enc', ASN1_ENCODING),
+    ('version', POINTER(ASN1_INTEGER)),
+    ('subject', POINTER(X509_NAME)),
+    ('pubkey', POINTER(X509_PUBKEY)),
+    ('attributes', POINTER(STACK)),
+]
+assert sizeof(X509_req_info_st) == 28, sizeof(X509_req_info_st)
+assert alignment(X509_req_info_st) == 4, alignment(X509_req_info_st)
+X509_REQ_INFO = X509_req_info_st
+class X509_req_st(Structure):
+    pass
+X509_req_st._fields_ = [
+    ('req_info', POINTER(X509_REQ_INFO)),
+    ('sig_alg', POINTER(X509_ALGOR)),
+    ('signature', POINTER(ASN1_BIT_STRING)),
+    ('references', c_int),
+]
+assert sizeof(X509_req_st) == 16, sizeof(X509_req_st)
+assert alignment(X509_req_st) == 4, alignment(X509_req_st)
+X509_REQ = X509_req_st
+class x509_cinf_st(Structure):
+    pass
+x509_cinf_st._fields_ = [
+    ('version', POINTER(ASN1_INTEGER)),
+    ('serialNumber', POINTER(ASN1_INTEGER)),
+    ('signature', POINTER(X509_ALGOR)),
+    ('issuer', POINTER(X509_NAME)),
+    ('validity', POINTER(X509_VAL)),
+    ('subject', POINTER(X509_NAME)),
+    ('key', POINTER(X509_PUBKEY)),
+    ('issuerUID', POINTER(ASN1_BIT_STRING)),
+    ('subjectUID', POINTER(ASN1_BIT_STRING)),
+    ('extensions', POINTER(STACK)),
+]
+assert sizeof(x509_cinf_st) == 40, sizeof(x509_cinf_st)
+assert alignment(x509_cinf_st) == 4, alignment(x509_cinf_st)
+X509_CINF = x509_cinf_st
+class x509_cert_aux_st(Structure):
+    pass
+x509_cert_aux_st._fields_ = [
+    ('trust', POINTER(STACK)),
+    ('reject', POINTER(STACK)),
+    ('alias', POINTER(ASN1_UTF8STRING)),
+    ('keyid', POINTER(ASN1_OCTET_STRING)),
+    ('other', POINTER(STACK)),
+]
+assert sizeof(x509_cert_aux_st) == 20, sizeof(x509_cert_aux_st)
+assert alignment(x509_cert_aux_st) == 4, alignment(x509_cert_aux_st)
+X509_CERT_AUX = x509_cert_aux_st
+class AUTHORITY_KEYID_st(Structure):
+    pass
+x509_st._fields_ = [
+    ('cert_info', POINTER(X509_CINF)),
+    ('sig_alg', POINTER(X509_ALGOR)),
+    ('signature', POINTER(ASN1_BIT_STRING)),
+    ('valid', c_int),
+    ('references', c_int),
+    ('name', STRING),
+    ('ex_data', CRYPTO_EX_DATA),
+    ('ex_pathlen', c_long),
+    ('ex_flags', c_ulong),
+    ('ex_kusage', c_ulong),
+    ('ex_xkusage', c_ulong),
+    ('ex_nscert', c_ulong),
+    ('skid', POINTER(ASN1_OCTET_STRING)),
+    ('akid', POINTER(AUTHORITY_KEYID_st)),
+    ('sha1_hash', c_ubyte * 20),
+    ('aux', POINTER(X509_CERT_AUX)),
+]
+assert sizeof(x509_st) == 84, sizeof(x509_st)
+assert alignment(x509_st) == 4, alignment(x509_st)
+AUTHORITY_KEYID_st._fields_ = [
+]
+class x509_trust_st(Structure):
+    pass
+x509_trust_st._fields_ = [
+    ('trust', c_int),
+    ('flags', c_int),
+    ('check_trust', CFUNCTYPE(c_int, POINTER(x509_trust_st), POINTER(X509), c_int)),
+    ('name', STRING),
+    ('arg1', c_int),
+    ('arg2', c_void_p),
+]
+assert sizeof(x509_trust_st) == 24, sizeof(x509_trust_st)
+assert alignment(x509_trust_st) == 4, alignment(x509_trust_st)
+X509_TRUST = x509_trust_st
+class X509_revoked_st(Structure):
+    pass
+X509_revoked_st._fields_ = [
+    ('serialNumber', POINTER(ASN1_INTEGER)),
+    ('revocationDate', POINTER(ASN1_TIME)),
+    ('extensions', POINTER(STACK)),
+    ('sequence', c_int),
+]
+assert sizeof(X509_revoked_st) == 16, sizeof(X509_revoked_st)
+assert alignment(X509_revoked_st) == 4, alignment(X509_revoked_st)
+X509_REVOKED = X509_revoked_st
+class X509_crl_info_st(Structure):
+    pass
+X509_crl_info_st._fields_ = [
+    ('version', POINTER(ASN1_INTEGER)),
+    ('sig_alg', POINTER(X509_ALGOR)),
+    ('issuer', POINTER(X509_NAME)),
+    ('lastUpdate', POINTER(ASN1_TIME)),
+    ('nextUpdate', POINTER(ASN1_TIME)),
+    ('revoked', POINTER(STACK)),
+    ('extensions', POINTER(STACK)),
+    ('enc', ASN1_ENCODING),
+]
+assert sizeof(X509_crl_info_st) == 40, sizeof(X509_crl_info_st)
+assert alignment(X509_crl_info_st) == 4, alignment(X509_crl_info_st)
+X509_CRL_INFO = X509_crl_info_st
+X509_crl_st._fields_ = [
+    ('crl', POINTER(X509_CRL_INFO)),
+    ('sig_alg', POINTER(X509_ALGOR)),
+    ('signature', POINTER(ASN1_BIT_STRING)),
+    ('references', c_int),
+]
+assert sizeof(X509_crl_st) == 16, sizeof(X509_crl_st)
+assert alignment(X509_crl_st) == 4, alignment(X509_crl_st)
+class private_key_st(Structure):
+    pass
+private_key_st._fields_ = [
+    ('version', c_int),
+    ('enc_algor', POINTER(X509_ALGOR)),
+    ('enc_pkey', POINTER(ASN1_OCTET_STRING)),
+    ('dec_pkey', POINTER(EVP_PKEY)),
+    ('key_length', c_int),
+    ('key_data', STRING),
+    ('key_free', c_int),
+    ('cipher', EVP_CIPHER_INFO),
+    ('references', c_int),
+]
+assert sizeof(private_key_st) == 52, sizeof(private_key_st)
+assert alignment(private_key_st) == 4, alignment(private_key_st)
+X509_PKEY = private_key_st
+class X509_info_st(Structure):
+    pass
+X509_info_st._fields_ = [
+    ('x509', POINTER(X509)),
+    ('crl', POINTER(X509_CRL)),
+    ('x_pkey', POINTER(X509_PKEY)),
+    ('enc_cipher', EVP_CIPHER_INFO),
+    ('enc_len', c_int),
+    ('enc_data', STRING),
+    ('references', c_int),
+]
+assert sizeof(X509_info_st) == 44, sizeof(X509_info_st)
+assert alignment(X509_info_st) == 4, alignment(X509_info_st)
+X509_INFO = X509_info_st
+class Netscape_spkac_st(Structure):
+    pass
+Netscape_spkac_st._fields_ = [
+    ('pubkey', POINTER(X509_PUBKEY)),
+    ('challenge', POINTER(ASN1_IA5STRING)),
+]
+assert sizeof(Netscape_spkac_st) == 8, sizeof(Netscape_spkac_st)
+assert alignment(Netscape_spkac_st) == 4, alignment(Netscape_spkac_st)
+NETSCAPE_SPKAC = Netscape_spkac_st
+class Netscape_spki_st(Structure):
+    pass
+Netscape_spki_st._fields_ = [
+    ('spkac', POINTER(NETSCAPE_SPKAC)),
+    ('sig_algor', POINTER(X509_ALGOR)),
+    ('signature', POINTER(ASN1_BIT_STRING)),
+]
+assert sizeof(Netscape_spki_st) == 12, sizeof(Netscape_spki_st)
+assert alignment(Netscape_spki_st) == 4, alignment(Netscape_spki_st)
+NETSCAPE_SPKI = Netscape_spki_st
+class Netscape_certificate_sequence(Structure):
+    pass
+Netscape_certificate_sequence._fields_ = [
+    ('type', POINTER(ASN1_OBJECT)),
+    ('certs', POINTER(STACK)),
+]
+assert sizeof(Netscape_certificate_sequence) == 8, sizeof(Netscape_certificate_sequence)
+assert alignment(Netscape_certificate_sequence) == 4, alignment(Netscape_certificate_sequence)
+NETSCAPE_CERT_SEQUENCE = Netscape_certificate_sequence
+class PBEPARAM_st(Structure):
+    pass
+PBEPARAM_st._fields_ = [
+    ('salt', POINTER(ASN1_OCTET_STRING)),
+    ('iter', POINTER(ASN1_INTEGER)),
+]
+assert sizeof(PBEPARAM_st) == 8, sizeof(PBEPARAM_st)
+assert alignment(PBEPARAM_st) == 4, alignment(PBEPARAM_st)
+PBEPARAM = PBEPARAM_st
+class PBE2PARAM_st(Structure):
+    pass
+PBE2PARAM_st._fields_ = [
+    ('keyfunc', POINTER(X509_ALGOR)),
+    ('encryption', POINTER(X509_ALGOR)),
+]
+assert sizeof(PBE2PARAM_st) == 8, sizeof(PBE2PARAM_st)
+assert alignment(PBE2PARAM_st) == 4, alignment(PBE2PARAM_st)
+PBE2PARAM = PBE2PARAM_st
+class PBKDF2PARAM_st(Structure):
+    pass
+PBKDF2PARAM_st._fields_ = [
+    ('salt', POINTER(ASN1_TYPE)),
+    ('iter', POINTER(ASN1_INTEGER)),
+    ('keylength', POINTER(ASN1_INTEGER)),
+    ('prf', POINTER(X509_ALGOR)),
+]
+assert sizeof(PBKDF2PARAM_st) == 16, sizeof(PBKDF2PARAM_st)
+assert alignment(PBKDF2PARAM_st) == 4, alignment(PBKDF2PARAM_st)
+PBKDF2PARAM = PBKDF2PARAM_st
+class pkcs8_priv_key_info_st(Structure):
+    pass
+pkcs8_priv_key_info_st._fields_ = [
+    ('broken', c_int),
+    ('version', POINTER(ASN1_INTEGER)),
+    ('pkeyalg', POINTER(X509_ALGOR)),
+    ('pkey', POINTER(ASN1_TYPE)),
+    ('attributes', POINTER(STACK)),
+]
+assert sizeof(pkcs8_priv_key_info_st) == 20, sizeof(pkcs8_priv_key_info_st)
+assert alignment(pkcs8_priv_key_info_st) == 4, alignment(pkcs8_priv_key_info_st)
+PKCS8_PRIV_KEY_INFO = pkcs8_priv_key_info_st
+class x509_hash_dir_st(Structure):
+    pass
+x509_hash_dir_st._fields_ = [
+    ('num_dirs', c_int),
+    ('dirs', POINTER(STRING)),
+    ('dirs_type', POINTER(c_int)),
+    ('num_dirs_alloced', c_int),
+]
+assert sizeof(x509_hash_dir_st) == 16, sizeof(x509_hash_dir_st)
+assert alignment(x509_hash_dir_st) == 4, alignment(x509_hash_dir_st)
+X509_HASH_DIR_CTX = x509_hash_dir_st
+class x509_file_st(Structure):
+    pass
+x509_file_st._fields_ = [
+    ('num_paths', c_int),
+    ('num_alloced', c_int),
+    ('paths', POINTER(STRING)),
+    ('path_type', POINTER(c_int)),
+]
+assert sizeof(x509_file_st) == 16, sizeof(x509_file_st)
+assert alignment(x509_file_st) == 4, alignment(x509_file_st)
+X509_CERT_FILE_CTX = x509_file_st
+class x509_object_st(Structure):
+    pass
+class N14x509_object_st4DOLLAR_14E(Union):
+    pass
+N14x509_object_st4DOLLAR_14E._fields_ = [
+    ('ptr', STRING),
+    ('x509', POINTER(X509)),
+    ('crl', POINTER(X509_CRL)),
+    ('pkey', POINTER(EVP_PKEY)),
+]
+assert sizeof(N14x509_object_st4DOLLAR_14E) == 4, sizeof(N14x509_object_st4DOLLAR_14E)
+assert alignment(N14x509_object_st4DOLLAR_14E) == 4, alignment(N14x509_object_st4DOLLAR_14E)
+x509_object_st._fields_ = [
+    ('type', c_int),
+    ('data', N14x509_object_st4DOLLAR_14E),
+]
+assert sizeof(x509_object_st) == 8, sizeof(x509_object_st)
+assert alignment(x509_object_st) == 4, alignment(x509_object_st)
+X509_OBJECT = x509_object_st
+class x509_lookup_st(Structure):
+    pass
+X509_LOOKUP = x509_lookup_st
+class x509_lookup_method_st(Structure):
+    pass
+x509_lookup_method_st._fields_ = [
+    ('name', STRING),
+    ('new_item', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))),
+    ('free', CFUNCTYPE(None, POINTER(X509_LOOKUP))),
+    ('init', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))),
+    ('shutdown', CFUNCTYPE(c_int, POINTER(X509_LOOKUP))),
+    ('ctrl', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_long, POINTER(STRING))),
+    ('get_by_subject', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(X509_OBJECT))),
+    ('get_by_issuer_serial', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(X509_NAME), POINTER(ASN1_INTEGER), POINTER(X509_OBJECT))),
+    ('get_by_fingerprint', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, POINTER(c_ubyte), c_int, POINTER(X509_OBJECT))),
+    ('get_by_alias', CFUNCTYPE(c_int, POINTER(X509_LOOKUP), c_int, STRING, c_int, POINTER(X509_OBJECT))),
+]
+assert sizeof(x509_lookup_method_st) == 40, sizeof(x509_lookup_method_st)
+assert alignment(x509_lookup_method_st) == 4, alignment(x509_lookup_method_st)
+X509_LOOKUP_METHOD = x509_lookup_method_st
+x509_store_st._fields_ = [
+    ('cache', c_int),
+    ('objs', POINTER(STACK)),
+    ('get_cert_methods', POINTER(STACK)),
+    ('flags', c_ulong),
+    ('purpose', c_int),
+    ('trust', c_int),
+    ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))),
+    ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))),
+    ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))),
+    ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))),
+    ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))),
+    ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))),
+    ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))),
+    ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))),
+    ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))),
+    ('ex_data', CRYPTO_EX_DATA),
+    ('references', c_int),
+    ('depth', c_int),
+]
+assert sizeof(x509_store_st) == 76, sizeof(x509_store_st)
+assert alignment(x509_store_st) == 4, alignment(x509_store_st)
+x509_lookup_st._fields_ = [
+    ('init', c_int),
+    ('skip', c_int),
+    ('method', POINTER(X509_LOOKUP_METHOD)),
+    ('method_data', STRING),
+    ('store_ctx', POINTER(X509_STORE)),
+]
+assert sizeof(x509_lookup_st) == 20, sizeof(x509_lookup_st)
+assert alignment(x509_lookup_st) == 4, alignment(x509_lookup_st)
+time_t = __darwin_time_t
+x509_store_ctx_st._fields_ = [
+    ('ctx', POINTER(X509_STORE)),
+    ('current_method', c_int),
+    ('cert', POINTER(X509)),
+    ('untrusted', POINTER(STACK)),
+    ('purpose', c_int),
+    ('trust', c_int),
+    ('check_time', time_t),
+    ('flags', c_ulong),
+    ('other_ctx', c_void_p),
+    ('verify', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))),
+    ('verify_cb', CFUNCTYPE(c_int, c_int, POINTER(X509_STORE_CTX))),
+    ('get_issuer', CFUNCTYPE(c_int, POINTER(POINTER(X509)), POINTER(X509_STORE_CTX), POINTER(X509))),
+    ('check_issued', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509), POINTER(X509))),
+    ('check_revocation', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))),
+    ('get_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(POINTER(X509_CRL)), POINTER(X509))),
+    ('check_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL))),
+    ('cert_crl', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX), POINTER(X509_CRL), POINTER(X509))),
+    ('cleanup', CFUNCTYPE(c_int, POINTER(X509_STORE_CTX))),
+    ('depth', c_int),
+    ('valid', c_int),
+    ('last_untrusted', c_int),
+    ('chain', POINTER(STACK)),
+    ('error_depth', c_int),
+    ('error', c_int),
+    ('current_cert', POINTER(X509)),
+    ('current_issuer', POINTER(X509)),
+    ('current_crl', POINTER(X509_CRL)),
+    ('ex_data', CRYPTO_EX_DATA),
+]
+assert sizeof(x509_store_ctx_st) == 116, sizeof(x509_store_ctx_st)
+assert alignment(x509_store_ctx_st) == 4, alignment(x509_store_ctx_st)
+va_list = __darwin_va_list
+__darwin_off_t = __int64_t
+fpos_t = __darwin_off_t
+class __sbuf(Structure):
+    pass
+__sbuf._fields_ = [
+    ('_base', POINTER(c_ubyte)),
+    ('_size', c_int),
+]
+assert sizeof(__sbuf) == 8, sizeof(__sbuf)
+assert alignment(__sbuf) == 4, alignment(__sbuf)
+class __sFILEX(Structure):
+    pass
+__sFILEX._fields_ = [
+]
+class __sFILE(Structure):
+    pass
+__sFILE._pack_ = 4
+__sFILE._fields_ = [
+    ('_p', POINTER(c_ubyte)),
+    ('_r', c_int),
+    ('_w', c_int),
+    ('_flags', c_short),
+    ('_file', c_short),
+    ('_bf', __sbuf),
+    ('_lbfsize', c_int),
+    ('_cookie', c_void_p),
+    ('_close', CFUNCTYPE(c_int, c_void_p)),
+    ('_read', CFUNCTYPE(c_int, c_void_p, STRING, c_int)),
+    ('_seek', CFUNCTYPE(fpos_t, c_void_p, c_longlong, c_int)),
+    ('_write', CFUNCTYPE(c_int, c_void_p, STRING, c_int)),
+    ('_ub', __sbuf),
+    ('_extra', POINTER(__sFILEX)),
+    ('_ur', c_int),
+    ('_ubuf', c_ubyte * 3),
+    ('_nbuf', c_ubyte * 1),
+    ('_lb', __sbuf),
+    ('_blksize', c_int),
+    ('_offset', fpos_t),
+]
+assert sizeof(__sFILE) == 88, sizeof(__sFILE)
+assert alignment(__sFILE) == 4, alignment(__sFILE)
+FILE = __sFILE
+ct_rune_t = __darwin_ct_rune_t
+rune_t = __darwin_rune_t
+class div_t(Structure):
+    pass
+div_t._fields_ = [
+    ('quot', c_int),
+    ('rem', c_int),
+]
+assert sizeof(div_t) == 8, sizeof(div_t)
+assert alignment(div_t) == 4, alignment(div_t)
+class ldiv_t(Structure):
+    pass
+ldiv_t._fields_ = [
+    ('quot', c_long),
+    ('rem', c_long),
+]
+assert sizeof(ldiv_t) == 8, sizeof(ldiv_t)
+assert alignment(ldiv_t) == 4, alignment(ldiv_t)
+class lldiv_t(Structure):
+    pass
+lldiv_t._pack_ = 4
+lldiv_t._fields_ = [
+    ('quot', c_longlong),
+    ('rem', c_longlong),
+]
+assert sizeof(lldiv_t) == 16, sizeof(lldiv_t)
+assert alignment(lldiv_t) == 4, alignment(lldiv_t)
+__darwin_dev_t = __int32_t
+dev_t = __darwin_dev_t
+__darwin_mode_t = __uint16_t
+mode_t = __darwin_mode_t
+class mcontext(Structure):
+    pass
+mcontext._fields_ = [
+]
+class mcontext64(Structure):
+    pass
+mcontext64._fields_ = [
+]
+class __darwin_pthread_handler_rec(Structure):
+    pass
+__darwin_pthread_handler_rec._fields_ = [
+    ('__routine', CFUNCTYPE(None, c_void_p)),
+    ('__arg', c_void_p),
+    ('__next', POINTER(__darwin_pthread_handler_rec)),
+]
+assert sizeof(__darwin_pthread_handler_rec) == 12, sizeof(__darwin_pthread_handler_rec)
+assert alignment(__darwin_pthread_handler_rec) == 4, alignment(__darwin_pthread_handler_rec)
+class _opaque_pthread_attr_t(Structure):
+    pass
+_opaque_pthread_attr_t._fields_ = [
+    ('__sig', c_long),
+    ('__opaque', c_char * 36),
+]
+assert sizeof(_opaque_pthread_attr_t) == 40, sizeof(_opaque_pthread_attr_t)
+assert alignment(_opaque_pthread_attr_t) == 4, alignment(_opaque_pthread_attr_t)
+class _opaque_pthread_cond_t(Structure):
+    pass
+_opaque_pthread_cond_t._fields_ = [
+    ('__sig', c_long),
+    ('__opaque', c_char * 24),
+]
+assert sizeof(_opaque_pthread_cond_t) == 28, sizeof(_opaque_pthread_cond_t)
+assert alignment(_opaque_pthread_cond_t) == 4, alignment(_opaque_pthread_cond_t)
+class _opaque_pthread_condattr_t(Structure):
+    pass
+_opaque_pthread_condattr_t._fields_ = [
+    ('__sig', c_long),
+    ('__opaque', c_char * 4),
+]
+assert sizeof(_opaque_pthread_condattr_t) == 8, sizeof(_opaque_pthread_condattr_t)
+assert alignment(_opaque_pthread_condattr_t) == 4, alignment(_opaque_pthread_condattr_t)
+class _opaque_pthread_mutex_t(Structure):
+    pass
+_opaque_pthread_mutex_t._fields_ = [
+    ('__sig', c_long),
+    ('__opaque', c_char * 40),
+]
+assert sizeof(_opaque_pthread_mutex_t) == 44, sizeof(_opaque_pthread_mutex_t)
+assert alignment(_opaque_pthread_mutex_t) == 4, alignment(_opaque_pthread_mutex_t)
+class _opaque_pthread_mutexattr_t(Structure):
+    pass
+_opaque_pthread_mutexattr_t._fields_ = [
+    ('__sig', c_long),
+    ('__opaque', c_char * 8),
+]
+assert sizeof(_opaque_pthread_mutexattr_t) == 12, sizeof(_opaque_pthread_mutexattr_t)
+assert alignment(_opaque_pthread_mutexattr_t) == 4, alignment(_opaque_pthread_mutexattr_t)
+class _opaque_pthread_once_t(Structure):
+    pass
+_opaque_pthread_once_t._fields_ = [
+    ('__sig', c_long),
+    ('__opaque', c_char * 4),
+]
+assert sizeof(_opaque_pthread_once_t) == 8, sizeof(_opaque_pthread_once_t)
+assert alignment(_opaque_pthread_once_t) == 4, alignment(_opaque_pthread_once_t)
+class _opaque_pthread_rwlock_t(Structure):
+    pass
+_opaque_pthread_rwlock_t._fields_ = [
+    ('__sig', c_long),
+    ('__opaque', c_char * 124),
+]
+assert sizeof(_opaque_pthread_rwlock_t) == 128, sizeof(_opaque_pthread_rwlock_t)
+assert alignment(_opaque_pthread_rwlock_t) == 4, alignment(_opaque_pthread_rwlock_t)
+class _opaque_pthread_rwlockattr_t(Structure):
+    pass
+_opaque_pthread_rwlockattr_t._fields_ = [
+    ('__sig', c_long),
+    ('__opaque', c_char * 12),
+]
+assert sizeof(_opaque_pthread_rwlockattr_t) == 16, sizeof(_opaque_pthread_rwlockattr_t)
+assert alignment(_opaque_pthread_rwlockattr_t) == 4, alignment(_opaque_pthread_rwlockattr_t)
+class _opaque_pthread_t(Structure):
+    pass
+_opaque_pthread_t._fields_ = [
+    ('__sig', c_long),
+    ('__cleanup_stack', POINTER(__darwin_pthread_handler_rec)),
+    ('__opaque', c_char * 596),
+]
+assert sizeof(_opaque_pthread_t) == 604, sizeof(_opaque_pthread_t)
+assert alignment(_opaque_pthread_t) == 4, alignment(_opaque_pthread_t)
+__darwin_blkcnt_t = __int64_t
+__darwin_blksize_t = __int32_t
+__darwin_fsblkcnt_t = c_uint
+__darwin_fsfilcnt_t = c_uint
+__darwin_gid_t = __uint32_t
+__darwin_id_t = __uint32_t
+__darwin_ino_t = __uint32_t
+__darwin_mach_port_name_t = __darwin_natural_t
+__darwin_mach_port_t = __darwin_mach_port_name_t
+__darwin_mcontext_t = POINTER(mcontext)
+__darwin_mcontext64_t = POINTER(mcontext64)
+__darwin_pid_t = __int32_t
+__darwin_pthread_attr_t = _opaque_pthread_attr_t
+__darwin_pthread_cond_t = _opaque_pthread_cond_t
+__darwin_pthread_condattr_t = _opaque_pthread_condattr_t
+__darwin_pthread_key_t = c_ulong
+__darwin_pthread_mutex_t = _opaque_pthread_mutex_t
+__darwin_pthread_mutexattr_t = _opaque_pthread_mutexattr_t
+__darwin_pthread_once_t = _opaque_pthread_once_t
+__darwin_pthread_rwlock_t = _opaque_pthread_rwlock_t
+__darwin_pthread_rwlockattr_t = _opaque_pthread_rwlockattr_t
+__darwin_pthread_t = POINTER(_opaque_pthread_t)
+__darwin_sigset_t = __uint32_t
+__darwin_suseconds_t = __int32_t
+__darwin_uid_t = __uint32_t
+__darwin_useconds_t = __uint32_t
+__darwin_uuid_t = c_ubyte * 16
+class sigaltstack(Structure):
+    pass
+sigaltstack._fields_ = [
+    ('ss_sp', c_void_p),
+    ('ss_size', __darwin_size_t),
+    ('ss_flags', c_int),
+]
+assert sizeof(sigaltstack) == 12, sizeof(sigaltstack)
+assert alignment(sigaltstack) == 4, alignment(sigaltstack)
+__darwin_stack_t = sigaltstack
+class ucontext(Structure):
+    pass
+ucontext._fields_ = [
+    ('uc_onstack', c_int),
+    ('uc_sigmask', __darwin_sigset_t),
+    ('uc_stack', __darwin_stack_t),
+    ('uc_link', POINTER(ucontext)),
+    ('uc_mcsize', __darwin_size_t),
+    ('uc_mcontext', __darwin_mcontext_t),
+]
+assert sizeof(ucontext) == 32, sizeof(ucontext)
+assert alignment(ucontext) == 4, alignment(ucontext)
+__darwin_ucontext_t = ucontext
+class ucontext64(Structure):
+    pass
+ucontext64._fields_ = [
+    ('uc_onstack', c_int),
+    ('uc_sigmask', __darwin_sigset_t),
+    ('uc_stack', __darwin_stack_t),
+    ('uc_link', POINTER(ucontext64)),
+    ('uc_mcsize', __darwin_size_t),
+    ('uc_mcontext64', __darwin_mcontext64_t),
+]
+assert sizeof(ucontext64) == 32, sizeof(ucontext64)
+assert alignment(ucontext64) == 4, alignment(ucontext64)
+__darwin_ucontext64_t = ucontext64
+class timeval(Structure):
+    pass
+timeval._fields_ = [
+    ('tv_sec', __darwin_time_t),
+    ('tv_usec', __darwin_suseconds_t),
+]
+assert sizeof(timeval) == 8, sizeof(timeval)
+assert alignment(timeval) == 4, alignment(timeval)
+rlim_t = __int64_t
+class rusage(Structure):
+    pass
+rusage._fields_ = [
+    ('ru_utime', timeval),
+    ('ru_stime', timeval),
+    ('ru_maxrss', c_long),
+    ('ru_ixrss', c_long),
+    ('ru_idrss', c_long),
+    ('ru_isrss', c_long),
+    ('ru_minflt', c_long),
+    ('ru_majflt', c_long),
+    ('ru_nswap', c_long),
+    ('ru_inblock', c_long),
+    ('ru_oublock', c_long),
+    ('ru_msgsnd', c_long),
+    ('ru_msgrcv', c_long),
+    ('ru_nsignals', c_long),
+    ('ru_nvcsw', c_long),
+    ('ru_nivcsw', c_long),
+]
+assert sizeof(rusage) == 72, sizeof(rusage)
+assert alignment(rusage) == 4, alignment(rusage)
+class rlimit(Structure):
+    pass
+rlimit._pack_ = 4
+rlimit._fields_ = [
+    ('rlim_cur', rlim_t),
+    ('rlim_max', rlim_t),
+]
+assert sizeof(rlimit) == 16, sizeof(rlimit)
+assert alignment(rlimit) == 4, alignment(rlimit)
+mcontext_t = __darwin_mcontext_t
+mcontext64_t = __darwin_mcontext64_t
+pthread_attr_t = __darwin_pthread_attr_t
+sigset_t = __darwin_sigset_t
+ucontext_t = __darwin_ucontext_t
+ucontext64_t = __darwin_ucontext64_t
+uid_t = __darwin_uid_t
+class sigval(Union):
+    pass
+sigval._fields_ = [
+    ('sival_int', c_int),
+    ('sival_ptr', c_void_p),
+]
+assert sizeof(sigval) == 4, sizeof(sigval)
+assert alignment(sigval) == 4, alignment(sigval)
+class sigevent(Structure):
+    pass
+sigevent._fields_ = [
+    ('sigev_notify', c_int),
+    ('sigev_signo', c_int),
+    ('sigev_value', sigval),
+    ('sigev_notify_function', CFUNCTYPE(None, sigval)),
+    ('sigev_notify_attributes', POINTER(pthread_attr_t)),
+]
+assert sizeof(sigevent) == 20, sizeof(sigevent)
+assert alignment(sigevent) == 4, alignment(sigevent)
+class __siginfo(Structure):
+    pass
+pid_t = __darwin_pid_t
+__siginfo._fields_ = [
+    ('si_signo', c_int),
+    ('si_errno', c_int),
+    ('si_code', c_int),
+    ('si_pid', pid_t),
+    ('si_uid', uid_t),
+    ('si_status', c_int),
+    ('si_addr', c_void_p),
+    ('si_value', sigval),
+    ('si_band', c_long),
+    ('pad', c_ulong * 7),
+]
+assert sizeof(__siginfo) == 64, sizeof(__siginfo)
+assert alignment(__siginfo) == 4, alignment(__siginfo)
+siginfo_t = __siginfo
+class __sigaction_u(Union):
+    pass
+__sigaction_u._fields_ = [
+    ('__sa_handler', CFUNCTYPE(None, c_int)),
+    ('__sa_sigaction', CFUNCTYPE(None, c_int, POINTER(__siginfo), c_void_p)),
+]
+assert sizeof(__sigaction_u) == 4, sizeof(__sigaction_u)
+assert alignment(__sigaction_u) == 4, alignment(__sigaction_u)
+class __sigaction(Structure):
+    pass
+__sigaction._fields_ = [
+    ('__sigaction_u', __sigaction_u),
+    ('sa_tramp', CFUNCTYPE(None, c_void_p, c_int, c_int, POINTER(siginfo_t), c_void_p)),
+    ('sa_mask', sigset_t),
+    ('sa_flags', c_int),
+]
+assert sizeof(__sigaction) == 16, sizeof(__sigaction)
+assert alignment(__sigaction) == 4, alignment(__sigaction)
+class sigaction(Structure):
+    pass
+sigaction._fields_ = [
+    ('__sigaction_u', __sigaction_u),
+    ('sa_mask', sigset_t),
+    ('sa_flags', c_int),
+]
+assert sizeof(sigaction) == 12, sizeof(sigaction)
+assert alignment(sigaction) == 4, alignment(sigaction)
+sig_t = CFUNCTYPE(None, c_int)
+stack_t = __darwin_stack_t
+class sigvec(Structure):
+    pass
+sigvec._fields_ = [
+    ('sv_handler', CFUNCTYPE(None, c_int)),
+    ('sv_mask', c_int),
+    ('sv_flags', c_int),
+]
+assert sizeof(sigvec) == 12, sizeof(sigvec)
+assert alignment(sigvec) == 4, alignment(sigvec)
+class sigstack(Structure):
+    pass
+sigstack._fields_ = [
+    ('ss_sp', STRING),
+    ('ss_onstack', c_int),
+]
+assert sizeof(sigstack) == 8, sizeof(sigstack)
+assert alignment(sigstack) == 4, alignment(sigstack)
+u_char = c_ubyte
+u_short = c_ushort
+u_int = c_uint
+u_long = c_ulong
+ushort = c_ushort
+uint = c_uint
+u_quad_t = u_int64_t
+quad_t = int64_t
+qaddr_t = POINTER(quad_t)
+caddr_t = STRING
+daddr_t = int32_t
+fixpt_t = u_int32_t
+blkcnt_t = __darwin_blkcnt_t
+blksize_t = __darwin_blksize_t
+gid_t = __darwin_gid_t
+in_addr_t = __uint32_t
+in_port_t = __uint16_t
+ino_t = __darwin_ino_t
+key_t = __int32_t
+nlink_t = __uint16_t
+off_t = __darwin_off_t
+segsz_t = int32_t
+swblk_t = int32_t
+clock_t = __darwin_clock_t
+ssize_t = __darwin_ssize_t
+useconds_t = __darwin_useconds_t
+suseconds_t = __darwin_suseconds_t
+fd_mask = __int32_t
+class fd_set(Structure):
+    pass
+fd_set._fields_ = [
+    ('fds_bits', __int32_t * 32),
+]
+assert sizeof(fd_set) == 128, sizeof(fd_set)
+assert alignment(fd_set) == 4, alignment(fd_set)
+pthread_cond_t = __darwin_pthread_cond_t
+pthread_condattr_t = __darwin_pthread_condattr_t
+pthread_mutex_t = __darwin_pthread_mutex_t
+pthread_mutexattr_t = __darwin_pthread_mutexattr_t
+pthread_once_t = __darwin_pthread_once_t
+pthread_rwlock_t = __darwin_pthread_rwlock_t
+pthread_rwlockattr_t = __darwin_pthread_rwlockattr_t
+pthread_t = __darwin_pthread_t
+pthread_key_t = __darwin_pthread_key_t
+fsblkcnt_t = __darwin_fsblkcnt_t
+fsfilcnt_t = __darwin_fsfilcnt_t
+
+# values for enumeration 'idtype_t'
+idtype_t = c_int # enum
+id_t = __darwin_id_t
+class wait(Union):
+    pass
+class N4wait3DOLLAR_3E(Structure):
+    pass
+N4wait3DOLLAR_3E._fields_ = [
+    ('w_Termsig', c_uint, 7),
+    ('w_Coredump', c_uint, 1),
+    ('w_Retcode', c_uint, 8),
+    ('w_Filler', c_uint, 16),
+]
+assert sizeof(N4wait3DOLLAR_3E) == 4, sizeof(N4wait3DOLLAR_3E)
+assert alignment(N4wait3DOLLAR_3E) == 4, alignment(N4wait3DOLLAR_3E)
+class N4wait3DOLLAR_4E(Structure):
+    pass
+N4wait3DOLLAR_4E._fields_ = [
+    ('w_Stopval', c_uint, 8),
+    ('w_Stopsig', c_uint, 8),
+    ('w_Filler', c_uint, 16),
+]
+assert sizeof(N4wait3DOLLAR_4E) == 4, sizeof(N4wait3DOLLAR_4E)
+assert alignment(N4wait3DOLLAR_4E) == 4, alignment(N4wait3DOLLAR_4E)
+wait._fields_ = [
+    ('w_status', c_int),
+    ('w_T', N4wait3DOLLAR_3E),
+    ('w_S', N4wait3DOLLAR_4E),
+]
+assert sizeof(wait) == 4, sizeof(wait)
+assert alignment(wait) == 4, alignment(wait)
+class timespec(Structure):
+    pass
+timespec._fields_ = [
+    ('tv_sec', time_t),
+    ('tv_nsec', c_long),
+]
+assert sizeof(timespec) == 8, sizeof(timespec)
+assert alignment(timespec) == 4, alignment(timespec)
+class tm(Structure):
+    pass
+tm._fields_ = [
+    ('tm_sec', c_int),
+    ('tm_min', c_int),
+    ('tm_hour', c_int),
+    ('tm_mday', c_int),
+    ('tm_mon', c_int),
+    ('tm_year', c_int),
+    ('tm_wday', c_int),
+    ('tm_yday', c_int),
+    ('tm_isdst', c_int),
+    ('tm_gmtoff', c_long),
+    ('tm_zone', STRING),
+]
+assert sizeof(tm) == 44, sizeof(tm)
+assert alignment(tm) == 4, alignment(tm)
+__gnuc_va_list = STRING
+ptrdiff_t = c_int
+int8_t = c_byte
+int16_t = c_short
+uint8_t = c_ubyte
+uint16_t = c_ushort
+uint32_t = c_uint
+uint64_t = c_ulonglong
+int_least8_t = int8_t
+int_least16_t = int16_t
+int_least32_t = int32_t
+int_least64_t = int64_t
+uint_least8_t = uint8_t
+uint_least16_t = uint16_t
+uint_least32_t = uint32_t
+uint_least64_t = uint64_t
+int_fast8_t = int8_t
+int_fast16_t = int16_t
+int_fast32_t = int32_t
+int_fast64_t = int64_t
+uint_fast8_t = uint8_t
+uint_fast16_t = uint16_t
+uint_fast32_t = uint32_t
+uint_fast64_t = uint64_t
+intptr_t = c_long
+uintptr_t = c_ulong
+intmax_t = c_longlong
+uintmax_t = c_ulonglong
+__all__ = ['ENGINE', 'pkcs7_enc_content_st', '__int16_t',
+           'X509_REVOKED', 'SSL_CTX', 'UIT_BOOLEAN',
+           '__darwin_time_t', 'ucontext64_t', 'int_fast32_t',
+           'pem_ctx_st', 'uint8_t', 'fpos_t', 'X509', 'COMP_CTX',
+           'tm', 'N10pem_ctx_st4DOLLAR_17E', 'swblk_t',
+           'ASN1_TEMPLATE', '__darwin_pthread_t', 'fixpt_t',
+           'BIO_METHOD', 'ASN1_PRINTABLESTRING', 'EVP_ENCODE_CTX',
+           'dh_method', 'bio_f_buffer_ctx_struct', 'in_port_t',
+           'X509_SIG', '__darwin_ssize_t', '__darwin_sigset_t',
+           'wait', 'uint_fast16_t', 'N12asn1_type_st4DOLLAR_11E',
+           'uint_least8_t', 'pthread_rwlock_t', 'ASN1_IA5STRING',
+           'fsfilcnt_t', 'ucontext', '__uint64_t', 'timespec',
+           'x509_cinf_st', 'COMP_METHOD', 'MD5_CTX', 'buf_mem_st',
+           'ASN1_ENCODING_st', 'PBEPARAM', 'X509_NAME_ENTRY',
+           '__darwin_va_list', 'ucontext_t', 'lhash_st',
+           'N4wait3DOLLAR_4E', '__darwin_uuid_t',
+           '_ossl_old_des_ks_struct', 'id_t', 'ASN1_BIT_STRING',
+           'va_list', '__darwin_wchar_t', 'pthread_key_t',
+           'pkcs7_signer_info_st', 'ASN1_METHOD', 'DSA_SIG', 'DSA',
+           'UIT_NONE', 'pthread_t', '__darwin_useconds_t',
+           'uint_fast8_t', 'UI_STRING', 'DES_cblock',
+           '__darwin_mcontext64_t', 'rlim_t', 'PEM_Encode_Seal_st',
+           'SHAstate_st', 'u_quad_t', 'openssl_fptr',
+           '_opaque_pthread_rwlockattr_t',
+           'N18x509_attributes_st4DOLLAR_13E',
+           '__darwin_pthread_rwlock_t', 'daddr_t', 'ui_string_st',
+           'x509_file_st', 'X509_req_info_st', 'int_least64_t',
+           'evp_Encode_Ctx_st', 'X509_OBJECTS', 'CRYPTO_EX_DATA',
+           '__int8_t', 'AUTHORITY_KEYID_st', '_opaque_pthread_attr_t',
+           'sigstack', 'EVP_CIPHER_CTX', 'X509_extension_st', 'pid_t',
+           'RSA_METHOD', 'PEM_USER', 'pem_recip_st', 'env_md_ctx_st',
+           'rc5_key_st', 'ui_st', 'X509_PUBKEY', 'u_int8_t',
+           'ASN1_ITEM_st', 'pkcs7_recip_info_st', 'ssl2_state_st',
+           'off_t', 'N10ssl_ctx_st4DOLLAR_18E', 'crypto_ex_data_st',
+           'ui_method_st', '__darwin_pthread_rwlockattr_t',
+           'CRYPTO_EX_dup', '__darwin_ino_t', '__sFILE',
+           'OSUnknownByteOrder', 'BN_MONT_CTX', 'ASN1_NULL', 'time_t',
+           'CRYPTO_EX_new', 'asn1_type_st', 'CRYPTO_EX_DATA_FUNCS',
+           'user_time_t', 'BIGNUM', 'pthread_rwlockattr_t',
+           'ASN1_VALUE_st', 'DH_METHOD', '__darwin_off_t',
+           '_opaque_pthread_t', 'bn_blinding_st', 'RSA', 'ssize_t',
+           'mcontext64_t', 'user_long_t', 'fsblkcnt_t', 'cert_st',
+           '__darwin_pthread_condattr_t', 'X509_PKEY',
+           '__darwin_id_t', '__darwin_nl_item', 'SSL2_STATE', 'FILE',
+           'pthread_mutexattr_t', 'size_t',
+           '_ossl_old_des_key_schedule', 'pkcs7_issuer_and_serial_st',
+           'sigval', 'CRYPTO_MEM_LEAK_CB', 'X509_NAME', 'blkcnt_t',
+           'uint_least16_t', '__darwin_dev_t', 'evp_cipher_info_st',
+           'BN_BLINDING', 'ssl3_state_st', 'uint_least64_t',
+           'user_addr_t', 'DES_key_schedule', 'RIPEMD160_CTX',
+           'u_char', 'X509_algor_st', 'uid_t', 'sess_cert_st',
+           'u_int64_t', 'u_int16_t', 'sigset_t', '__darwin_ptrdiff_t',
+           'ASN1_CTX', 'STACK', '__int32_t', 'UI_METHOD',
+           'NETSCAPE_SPKI', 'UIT_PROMPT', 'st_CRYPTO_EX_DATA_IMPL',
+           'cast_key_st', 'X509_HASH_DIR_CTX', 'sigevent',
+           'user_ssize_t', 'clock_t', 'aes_key_st',
+           '__darwin_socklen_t', '__darwin_intptr_t', 'int_fast64_t',
+           'asn1_string_table_st', 'uint_fast32_t',
+           'ASN1_VISIBLESTRING', 'DSA_SIG_st', 'obj_name_st',
+           'X509_LOOKUP_METHOD', 'u_int32_t', 'EVP_CIPHER_INFO',
+           '__gnuc_va_list', 'AES_KEY', 'PKCS7_ISSUER_AND_SERIAL',
+           'BN_CTX', '__darwin_blkcnt_t', 'key_t', 'SHA_CTX',
+           'pkcs7_signed_st', 'SSL', 'N10pem_ctx_st4DOLLAR_16E',
+           'pthread_attr_t', 'EVP_MD', 'uint', 'ASN1_BOOLEAN',
+           'ino_t', '__darwin_clock_t', 'ASN1_OCTET_STRING',
+           'asn1_ctx_st', 'BIO_F_BUFFER_CTX', 'bn_mont_ctx_st',
+           'X509_REQ_INFO', 'PEM_CTX', 'sigvec',
+           '__darwin_pthread_mutexattr_t', 'x509_attributes_st',
+           'stack_t', '__darwin_mode_t', '__mbstate_t',
+           'asn1_object_st', 'ASN1_ENCODING', '__uint8_t',
+           'LHASH_NODE', 'PKCS7_SIGNER_INFO', 'asn1_method_st',
+           'stack_st', 'bio_info_cb', 'div_t', 'UIT_VERIFY',
+           'PBEPARAM_st', 'N4wait3DOLLAR_3E', 'quad_t', '__siginfo',
+           '__darwin_mbstate_t', 'rsa_st', 'ASN1_UNIVERSALSTRING',
+           'uint64_t', 'ssl_comp_st', 'X509_OBJECT', 'pthread_cond_t',
+           'DH', '__darwin_wctype_t', 'PKCS7_ENVELOPE', 'ASN1_TLC_st',
+           'sig_atomic_t', 'BIO', 'nlink_t', 'BUF_MEM', 'SSL3_RECORD',
+           'bio_method_st', 'timeval', 'UI_string_types', 'BIO_dummy',
+           'ssl_ctx_st', 'NETSCAPE_CERT_SEQUENCE',
+           'BIT_STRING_BITNAME_st', '__darwin_pthread_attr_t',
+           'int8_t', '__darwin_wint_t', 'OBJ_NAME',
+           'PKCS8_PRIV_KEY_INFO', 'PBE2PARAM_st',
+           'LHASH_DOALL_FN_TYPE', 'x509_st', 'X509_VAL', 'dev_t',
+           'ASN1_TEMPLATE_st', 'MD5state_st', '__uint16_t',
+           'LHASH_DOALL_ARG_FN_TYPE', 'mdc2_ctx_st', 'SSL3_STATE',
+           'ssl3_buffer_st', 'ASN1_ITEM_EXP',
+           '_opaque_pthread_condattr_t', 'mode_t', 'ASN1_VALUE',
+           'qaddr_t', '__darwin_gid_t', 'EVP_PKEY', 'CRYPTO_EX_free',
+           '_ossl_old_des_cblock', 'X509_INFO', 'asn1_string_st',
+           'intptr_t', 'UIT_INFO', 'int_fast8_t', 'sigaltstack',
+           'env_md_st', 'LHASH', '__darwin_ucontext_t',
+           'PKCS7_SIGN_ENVELOPE', '__darwin_mcontext_t', 'ct_rune_t',
+           'MD2_CTX', 'pthread_once_t', 'SSL3_BUFFER', 'fd_mask',
+           'ASN1_TYPE', 'PKCS7_SIGNED', 'ssl3_record_st', 'BF_KEY',
+           'MD4state_st', 'MD4_CTX', 'int16_t', 'SSL_CIPHER',
+           'rune_t', 'X509_TRUST', 'siginfo_t', 'X509_STORE',
+           '__sbuf', 'X509_STORE_CTX', '__darwin_blksize_t', 'ldiv_t',
+           'ASN1_TIME', 'SSL_METHOD', 'X509_LOOKUP',
+           'Netscape_spki_st', 'P_PID', 'sigaction', 'sig_t',
+           'hostent', 'x509_cert_aux_st', '_opaque_pthread_cond_t',
+           'segsz_t', 'ushort', '__darwin_ct_rune_t', 'fd_set',
+           'BN_RECP_CTX', 'x509_lookup_st', 'uint16_t', 'pkcs7_st',
+           'asn1_header_st', '__darwin_pthread_key_t',
+           'x509_trust_st', '__darwin_pthread_handler_rec', 'int32_t',
+           'X509_CRL_INFO', 'N11evp_pkey_st4DOLLAR_12E', 'MDC2_CTX',
+           'N23_ossl_old_des_ks_struct4DOLLAR_10E', 'ASN1_HEADER',
+           'X509_crl_info_st', 'LHASH_HASH_FN_TYPE',
+           '_opaque_pthread_mutexattr_t', 'ssl_st',
+           'N8pkcs7_st4DOLLAR_15E', 'evp_pkey_st',
+           'pkcs7_signedandenveloped_st', '__darwin_mach_port_t',
+           'EVP_PBE_KEYGEN', '_opaque_pthread_mutex_t',
+           'ASN1_UTCTIME', 'mcontext', 'crypto_ex_data_func_st',
+           'u_long', 'PBKDF2PARAM_st', 'rc4_key_st', 'DSA_METHOD',
+           'EVP_CIPHER', 'BIT_STRING_BITNAME', 'PKCS7_RECIP_INFO',
+           'ssl3_enc_method', 'X509_CERT_AUX', 'uintmax_t',
+           'int_fast16_t', 'RC5_32_KEY', 'ucontext64', 'ASN1_INTEGER',
+           'u_short', 'N14x509_object_st4DOLLAR_14E', 'mcontext64',
+           'X509_sig_st', 'ASN1_GENERALSTRING', 'PKCS7', '__sFILEX',
+           'X509_name_entry_st', 'ssl_session_st', 'caddr_t',
+           'bignum_st', 'X509_CINF', '__darwin_pthread_cond_t',
+           'ASN1_TLC', 'PKCS7_ENCRYPT', 'NETSCAPE_SPKAC',
+           'Netscape_spkac_st', 'idtype_t', 'UIT_ERROR',
+           'uint_fast64_t', 'in_addr_t', 'pthread_mutex_t',
+           '__int64_t', 'ASN1_BMPSTRING', 'uint32_t',
+           'PEM_ENCODE_SEAL_CTX', 'suseconds_t', 'ASN1_OBJECT',
+           'X509_val_st', 'private_key_st', 'CRYPTO_dynlock',
+           'X509_objects_st', 'CRYPTO_EX_DATA_IMPL',
+           'pthread_condattr_t', 'PKCS7_DIGEST', 'uint_least32_t',
+           'ASN1_STRING', '__uint32_t', 'P_PGID', 'rsa_meth_st',
+           'X509_crl_st', 'RC2_KEY', '__darwin_fsfilcnt_t',
+           'X509_revoked_st', 'PBE2PARAM', 'blksize_t',
+           'Netscape_certificate_sequence', 'ssl_cipher_st',
+           'bignum_ctx', 'register_t', 'ASN1_UTF8STRING',
+           'pkcs7_encrypted_st', 'RC4_KEY', '__darwin_ucontext64_t',
+           'N13ssl2_state_st4DOLLAR_19E', 'bn_recp_ctx_st',
+           'CAST_KEY', 'X509_ATTRIBUTE', '__darwin_suseconds_t',
+           '__sigaction', 'user_ulong_t', 'syscall_arg_t',
+           'evp_cipher_ctx_st', 'X509_ALGOR', 'mcontext_t',
+           'const_DES_cblock', '__darwin_fsblkcnt_t', 'dsa_st',
+           'int_least8_t', 'MD2state_st', 'X509_EXTENSION',
+           'GEN_SESSION_CB', 'int_least16_t', '__darwin_wctrans_t',
+           'PBKDF2PARAM', 'x509_lookup_method_st', 'pem_password_cb',
+           'X509_info_st', 'x509_store_st', '__darwin_natural_t',
+           'X509_pubkey_st', 'pkcs7_digest_st', '__darwin_size_t',
+           'ASN1_STRING_TABLE', 'OSLittleEndian', 'RIPEMD160state_st',
+           'pkcs7_enveloped_st', 'UI', 'ptrdiff_t', 'X509_REQ',
+           'CRYPTO_dynlock_value', 'X509_req_st', 'x509_store_ctx_st',
+           'N13ssl3_state_st4DOLLAR_20E', 'lhash_node_st',
+           '__darwin_pthread_mutex_t', 'LHASH_COMP_FN_TYPE',
+           '__darwin_rune_t', 'rlimit', '__darwin_pthread_once_t',
+           'OSBigEndian', 'uintptr_t', '__darwin_uid_t', 'u_int',
+           'ASN1_T61STRING', 'gid_t', 'ssl_method_st', 'ASN1_ITEM',
+           'ASN1_ENUMERATED', '_opaque_pthread_rwlock_t',
+           'pkcs8_priv_key_info_st', 'intmax_t', 'sigcontext',
+           'X509_CRL', 'rc2_key_st', 'engine_st', 'x509_object_st',
+           '_opaque_pthread_once_t', 'DES_ks', 'SSL_COMP',
+           'dsa_method', 'int64_t', 'bio_st', 'bf_key_st',
+           'ASN1_GENERALIZEDTIME', 'PKCS7_ENC_CONTENT',
+           '__darwin_pid_t', 'lldiv_t', 'comp_method_st',
+           'EVP_MD_CTX', 'evp_cipher_st', 'X509_name_st',
+           'x509_hash_dir_st', '__darwin_mach_port_name_t',
+           'useconds_t', 'user_size_t', 'SSL_SESSION', 'rusage',
+           'ssl_crock_st', 'int_least32_t', '__sigaction_u', 'dh_st',
+           'P_ALL', '__darwin_stack_t', 'N6DES_ks3DOLLAR_9E',
+           'comp_ctx_st', 'X509_CERT_FILE_CTX']
diff --git a/lib3/2to3/lib2to3/tests/data/py2_test_grammar.py b/lib3/2to3/lib2to3/tests/data/py2_test_grammar.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/py2_test_grammar.py
@@ -0,0 +1,974 @@
+# Python test set -- part 1, grammar.
+# This just tests whether the parser accepts them all.
+
+# NOTE: When you run this test as a script from the command line, you
+# get warnings about certain hex/oct constants.  Since those are
+# issued by the parser, you can't suppress them by adding a
+# filterwarnings() call to this module.  Therefore, to shut up the
+# regression test, the filterwarnings() call has been added to
+# regrtest.py.
+
+from test.test_support import run_unittest, check_syntax_error
+import unittest
+import sys
+# testing import *
+from sys import *
+
+class TokenTests(unittest.TestCase):
+
+    def testBackslash(self):
+        # Backslash means line continuation:
+        x = 1 \
+        + 1
+        self.assertEquals(x, 2, 'backslash for line continuation')
+
+        # Backslash does not means continuation in comments :\
+        x = 0
+        self.assertEquals(x, 0, 'backslash ending comment')
+
+    def testPlainIntegers(self):
+        self.assertEquals(0xff, 255)
+        self.assertEquals(0o377, 255)
+        self.assertEquals(2147483647, 0o17777777777)
+        # "0x" is not a valid literal
+        self.assertRaises(SyntaxError, eval, "0x")
+        from sys import maxsize
+        if maxint == 2147483647:
+            self.assertEquals(-2147483647-1, -0o20000000000)
+            # XXX -2147483648
+            self.assert_(0o37777777777 > 0)
+            self.assert_(0xffffffff > 0)
+            for s in '2147483648', '040000000000', '0x100000000':
+                try:
+                    x = eval(s)
+                except OverflowError:
+                    self.fail("OverflowError on huge integer literal %r" % s)
+        elif maxint == 9223372036854775807:
+            self.assertEquals(-9223372036854775807-1, -0o1000000000000000000000)
+            self.assert_(0o1777777777777777777777 > 0)
+            self.assert_(0xffffffffffffffff > 0)
+            for s in '9223372036854775808', '02000000000000000000000', \
+                     '0x10000000000000000':
+                try:
+                    x = eval(s)
+                except OverflowError:
+                    self.fail("OverflowError on huge integer literal %r" % s)
+        else:
+            self.fail('Weird maxint value %r' % maxint)
+
+    def testLongIntegers(self):
+        x = 0
+        x = 0
+        x = 0xffffffffffffffff
+        x = 0xffffffffffffffff
+        x = 077777777777777777
+        x = 077777777777777777
+        x = 123456789012345678901234567890
+        x = 123456789012345678901234567890
+
+    def testFloats(self):
+        x = 3.14
+        x = 314.
+        x = 0.314
+        # XXX x = 000.314
+        x = .314
+        x = 3e14
+        x = 3E14
+        x = 3e-14
+        x = 3e+14
+        x = 3.e14
+        x = .3e14
+        x = 3.1e4
+
+    def testStringLiterals(self):
+        x = ''; y = ""; self.assert_(len(x) == 0 and x == y)
+        x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39)
+        x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34)
+        x = "doesn't \"shrink\" does it"
+        y = 'doesn\'t "shrink" does it'
+        self.assert_(len(x) == 24 and x == y)
+        x = "does \"shrink\" doesn't it"
+        y = 'does "shrink" doesn\'t it'
+        self.assert_(len(x) == 24 and x == y)
+        x = """
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+"""
+        y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
+        self.assertEquals(x, y)
+        y = '''
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+'''
+        self.assertEquals(x, y)
+        y = "\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the 'lazy' dog.\n\
+"
+        self.assertEquals(x, y)
+        y = '\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the \'lazy\' dog.\n\
+'
+        self.assertEquals(x, y)
+
+
+class GrammarTests(unittest.TestCase):
+
+    # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+    # XXX can't test in a script -- this rule is only used when interactive
+
+    # file_input: (NEWLINE | stmt)* ENDMARKER
+    # Being tested as this very moment this very module
+
+    # expr_input: testlist NEWLINE
+    # XXX Hard to test -- used only in calls to input()
+
+    def testEvalInput(self):
+        # testlist ENDMARKER
+        x = eval('1, 0 or 1')
+
+    def testFuncdef(self):
+        ### 'def' NAME parameters ':' suite
+        ### parameters: '(' [varargslist] ')'
+        ### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME]
+        ###            | ('**'|'*' '*') NAME)
+        ###            | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+        ### fpdef: NAME | '(' fplist ')'
+        ### fplist: fpdef (',' fpdef)* [',']
+        ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
+        ### argument: [test '='] test   # Really [keyword '='] test
+        def f1(): pass
+        f1()
+        f1(*())
+        f1(*(), **{})
+        def f2(one_argument): pass
+        def f3(two, arguments): pass
+        def f4(two, xxx_todo_changeme): (compound, (argument, list)) = xxx_todo_changeme; pass
+        def f5(xxx_todo_changeme1, two): (compound, first) = xxx_todo_changeme1; pass
+        self.assertEquals(f2.__code__.co_varnames, ('one_argument',))
+        self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments'))
+        if sys.platform.startswith('java'):
+            self.assertEquals(f4.__code__.co_varnames,
+                   ('two', '(compound, (argument, list))', 'compound', 'argument',
+                                'list',))
+            self.assertEquals(f5.__code__.co_varnames,
+                   ('(compound, first)', 'two', 'compound', 'first'))
+        else:
+            self.assertEquals(f4.__code__.co_varnames,
+                  ('two', '.1', 'compound', 'argument',  'list'))
+            self.assertEquals(f5.__code__.co_varnames,
+                  ('.0', 'two', 'compound', 'first'))
+        def a1(one_arg,): pass
+        def a2(two, args,): pass
+        def v0(*rest): pass
+        def v1(a, *rest): pass
+        def v2(a, b, *rest): pass
+        def v3(a, xxx_todo_changeme2, *rest): (b, c) = xxx_todo_changeme2; return a, b, c, rest
+
+        f1()
+        f2(1)
+        f2(1,)
+        f3(1, 2)
+        f3(1, 2,)
+        f4(1, (2, (3, 4)))
+        v0()
+        v0(1)
+        v0(1,)
+        v0(1,2)
+        v0(1,2,3,4,5,6,7,8,9,0)
+        v1(1)
+        v1(1,)
+        v1(1,2)
+        v1(1,2,3)
+        v1(1,2,3,4,5,6,7,8,9,0)
+        v2(1,2)
+        v2(1,2,3)
+        v2(1,2,3,4)
+        v2(1,2,3,4,5,6,7,8,9,0)
+        v3(1,(2,3))
+        v3(1,(2,3),4)
+        v3(1,(2,3),4,5,6,7,8,9,0)
+
+        # ceval unpacks the formal arguments into the first argcount names;
+        # thus, the names nested inside tuples must appear after these names.
+        if sys.platform.startswith('java'):
+            self.assertEquals(v3.__code__.co_varnames, ('a', '(b, c)', 'rest', 'b', 'c'))
+        else:
+            self.assertEquals(v3.__code__.co_varnames, ('a', '.1', 'rest', 'b', 'c'))
+        self.assertEquals(v3(1, (2, 3), 4), (1, 2, 3, (4,)))
+        def d01(a=1): pass
+        d01()
+        d01(1)
+        d01(*(1,))
+        d01(**{'a':2})
+        def d11(a, b=1): pass
+        d11(1)
+        d11(1, 2)
+        d11(1, **{'b':2})
+        def d21(a, b, c=1): pass
+        d21(1, 2)
+        d21(1, 2, 3)
+        d21(*(1, 2, 3))
+        d21(1, *(2, 3))
+        d21(1, 2, *(3,))
+        d21(1, 2, **{'c':3})
+        def d02(a=1, b=2): pass
+        d02()
+        d02(1)
+        d02(1, 2)
+        d02(*(1, 2))
+        d02(1, *(2,))
+        d02(1, **{'b':2})
+        d02(**{'a': 1, 'b': 2})
+        def d12(a, b=1, c=2): pass
+        d12(1)
+        d12(1, 2)
+        d12(1, 2, 3)
+        def d22(a, b, c=1, d=2): pass
+        d22(1, 2)
+        d22(1, 2, 3)
+        d22(1, 2, 3, 4)
+        def d01v(a=1, *rest): pass
+        d01v()
+        d01v(1)
+        d01v(1, 2)
+        d01v(*(1, 2, 3, 4))
+        d01v(*(1,))
+        d01v(**{'a':2})
+        def d11v(a, b=1, *rest): pass
+        d11v(1)
+        d11v(1, 2)
+        d11v(1, 2, 3)
+        def d21v(a, b, c=1, *rest): pass
+        d21v(1, 2)
+        d21v(1, 2, 3)
+        d21v(1, 2, 3, 4)
+        d21v(*(1, 2, 3, 4))
+        d21v(1, 2, **{'c': 3})
+        def d02v(a=1, b=2, *rest): pass
+        d02v()
+        d02v(1)
+        d02v(1, 2)
+        d02v(1, 2, 3)
+        d02v(1, *(2, 3, 4))
+        d02v(**{'a': 1, 'b': 2})
+        def d12v(a, b=1, c=2, *rest): pass
+        d12v(1)
+        d12v(1, 2)
+        d12v(1, 2, 3)
+        d12v(1, 2, 3, 4)
+        d12v(*(1, 2, 3, 4))
+        d12v(1, 2, *(3, 4, 5))
+        d12v(1, *(2,), **{'c': 3})
+        def d22v(a, b, c=1, d=2, *rest): pass
+        d22v(1, 2)
+        d22v(1, 2, 3)
+        d22v(1, 2, 3, 4)
+        d22v(1, 2, 3, 4, 5)
+        d22v(*(1, 2, 3, 4))
+        d22v(1, 2, *(3, 4, 5))
+        d22v(1, *(2, 3), **{'d': 4})
+        def d31v(xxx_todo_changeme3): (x) = xxx_todo_changeme3; pass
+        d31v(1)
+        def d32v(xxx_todo_changeme4): (x,) = xxx_todo_changeme4; pass
+        d32v((1,))
+
+        # keyword arguments after *arglist
+        def f(*args, **kwargs):
+            return args, kwargs
+        self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4),
+                                                    {'x':2, 'y':5}))
+        self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)")
+        self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)")
+
+        # Check ast errors in *args and *kwargs
+        check_syntax_error(self, "f(*g(1=2))")
+        check_syntax_error(self, "f(**g(1=2))")
+
+    def testLambdef(self):
+        ### lambdef: 'lambda' [varargslist] ':' test
+        l1 = lambda : 0
+        self.assertEquals(l1(), 0)
+        l2 = lambda : a[d] # XXX just testing the expression
+        l3 = lambda : [2 < x for x in [-1, 3, 0]]
+        self.assertEquals(l3(), [0, 1, 0])
+        l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
+        self.assertEquals(l4(), 1)
+        l5 = lambda x, y, z=2: x + y + z
+        self.assertEquals(l5(1, 2), 5)
+        self.assertEquals(l5(1, 2, 3), 6)
+        check_syntax_error(self, "lambda x: x = 2")
+        check_syntax_error(self, "lambda (None,): None")
+
+    ### stmt: simple_stmt | compound_stmt
+    # Tested below
+
+    def testSimpleStmt(self):
+        ### simple_stmt: small_stmt (';' small_stmt)* [';']
+        x = 1; pass; del x
+        def foo():
+            # verify statments that end with semi-colons
+            x = 1; pass; del x;
+        foo()
+
+    ### small_stmt: expr_stmt | print_stmt  | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt
+    # Tested below
+
+    def testExprStmt(self):
+        # (exprlist '=')* exprlist
+        1
+        1, 2, 3
+        x = 1
+        x = 1, 2, 3
+        x = y = z = 1, 2, 3
+        x, y, z = 1, 2, 3
+        abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
+
+        check_syntax_error(self, "x + 1 = 1")
+        check_syntax_error(self, "a + 1 = b + 2")
+
+    def testPrintStmt(self):
+        # 'print' (test ',')* [test]
+        import io
+
+        # Can't test printing to real stdout without comparing output
+        # which is not available in unittest.
+        save_stdout = sys.stdout
+        sys.stdout = io.StringIO()
+
+        print(1, 2, 3)
+        print(1, 2, 3, end=' ')
+        print()
+        print(0 or 1, 0 or 1, end=' ')
+        print(0 or 1)
+
+        # 'print' '>>' test ','
+        print(1, 2, 3, file=sys.stdout)
+        print(1, 2, 3, end=' ', file=sys.stdout)
+        print(file=sys.stdout)
+        print(0 or 1, 0 or 1, end=' ', file=sys.stdout)
+        print(0 or 1, file=sys.stdout)
+
+        # test printing to an instance
+        class Gulp:
+            def write(self, msg): pass
+
+        gulp = Gulp()
+        print(1, 2, 3, file=gulp)
+        print(1, 2, 3, end=' ', file=gulp)
+        print(file=gulp)
+        print(0 or 1, 0 or 1, end=' ', file=gulp)
+        print(0 or 1, file=gulp)
+
+        # test print >> None
+        def driver():
+            oldstdout = sys.stdout
+            sys.stdout = Gulp()
+            try:
+                tellme(Gulp())
+                tellme()
+            finally:
+                sys.stdout = oldstdout
+
+        # we should see this once
+        def tellme(file=sys.stdout):
+            print('hello world', file=file)
+
+        driver()
+
+        # we should not see this at all
+        def tellme(file=None):
+            print('goodbye universe', file=file)
+
+        driver()
+
+        self.assertEqual(sys.stdout.getvalue(), '''\
+1 2 3
+1 2 3
+1 1 1
+1 2 3
+1 2 3
+1 1 1
+hello world
+''')
+        sys.stdout = save_stdout
+
+        # syntax errors
+        check_syntax_error(self, 'print ,')
+        check_syntax_error(self, 'print >> x,')
+
+    def testDelStmt(self):
+        # 'del' exprlist
+        abc = [1,2,3]
+        x, y, z = abc
+        xyz = x, y, z
+
+        del abc
+        del x, y, (z, xyz)
+
+    def testPassStmt(self):
+        # 'pass'
+        pass
+
+    # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
+    # Tested below
+
+    def testBreakStmt(self):
+        # 'break'
+        while 1: break
+
+    def testContinueStmt(self):
+        # 'continue'
+        i = 1
+        while i: i = 0; continue
+
+        msg = ""
+        while not msg:
+            msg = "ok"
+            try:
+                continue
+                msg = "continue failed to continue inside try"
+            except:
+                msg = "continue inside try called except block"
+        if msg != "ok":
+            self.fail(msg)
+
+        msg = ""
+        while not msg:
+            msg = "finally block not called"
+            try:
+                continue
+            finally:
+                msg = "ok"
+        if msg != "ok":
+            self.fail(msg)
+
+    def test_break_continue_loop(self):
+        # This test warrants an explanation. It is a test specifically for SF bugs
+        # #463359 and #462937. The bug is that a 'break' statement executed or
+        # exception raised inside a try/except inside a loop, *after* a continue
+        # statement has been executed in that loop, will cause the wrong number of
+        # arguments to be popped off the stack and the instruction pointer reset to
+        # a very small number (usually 0.) Because of this, the following test
+        # *must* written as a function, and the tracking vars *must* be function
+        # arguments with default values. Otherwise, the test will loop and loop.
+
+        def test_inner(extra_burning_oil = 1, count=0):
+            big_hippo = 2
+            while big_hippo:
+                count += 1
+                try:
+                    if extra_burning_oil and big_hippo == 1:
+                        extra_burning_oil -= 1
+                        break
+                    big_hippo -= 1
+                    continue
+                except:
+                    raise
+            if count > 2 or big_hippo != 1:
+                self.fail("continue then break in try/except in loop broken!")
+        test_inner()
+
+    def testReturn(self):
+        # 'return' [testlist]
+        def g1(): return
+        def g2(): return 1
+        g1()
+        x = g2()
+        check_syntax_error(self, "class foo:return 1")
+
+    def testYield(self):
+        check_syntax_error(self, "class foo:yield 1")
+
+    def testRaise(self):
+        # 'raise' test [',' test]
+        try: raise RuntimeError('just testing')
+        except RuntimeError: pass
+        try: raise KeyboardInterrupt
+        except KeyboardInterrupt: pass
+
+    def testImport(self):
+        # 'import' dotted_as_names
+        import sys
+        import time, sys
+        # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names)
+        from time import time
+        from time import (time)
+        # not testable inside a function, but already done at top of the module
+        # from sys import *
+        from sys import path, argv
+        from sys import (path, argv)
+        from sys import (path, argv,)
+
+    def testGlobal(self):
+        # 'global' NAME (',' NAME)*
+        global a
+        global a, b
+        global one, two, three, four, five, six, seven, eight, nine, ten
+
+    def testExec(self):
+        # 'exec' expr ['in' expr [',' expr]]
+        z = None
+        del z
+        exec('z=1+1\n')
+        if z != 2: self.fail('exec \'z=1+1\'\\n')
+        del z
+        exec('z=1+1')
+        if z != 2: self.fail('exec \'z=1+1\'')
+        z = None
+        del z
+        import types
+        if hasattr(types, "UnicodeType"):
+            exec(r"""if 1:
+            exec u'z=1+1\n'
+            if z != 2: self.fail('exec u\'z=1+1\'\\n')
+            del z
+            exec u'z=1+1'
+            if z != 2: self.fail('exec u\'z=1+1\'')""")
+        g = {}
+        exec('z = 1', g)
+        if '__builtins__' in g: del g['__builtins__']
+        if g != {'z': 1}: self.fail('exec \'z = 1\' in g')
+        g = {}
+        l = {}
+
+        import warnings
+        warnings.filterwarnings("ignore", "global statement", module="<string>")
+        exec('global a; a = 1; b = 2', g, l)
+        if '__builtins__' in g: del g['__builtins__']
+        if '__builtins__' in l: del l['__builtins__']
+        if (g, l) != ({'a':1}, {'b':2}):
+            self.fail('exec ... in g (%s), l (%s)' %(g,l))
+
+    def testAssert(self):
+        # assert_stmt: 'assert' test [',' test]
+        assert 1
+        assert 1, 1
+        assert lambda x:x
+        assert 1, lambda x:x+1
+        try:
+            assert 0, "msg"
+        except AssertionError as e:
+            self.assertEquals(e.args[0], "msg")
+        else:
+            if __debug__:
+                self.fail("AssertionError not raised by assert 0")
+
+    ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+    # Tested below
+
+    def testIf(self):
+        # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+        if 1: pass
+        if 1: pass
+        else: pass
+        if 0: pass
+        elif 0: pass
+        if 0: pass
+        elif 0: pass
+        elif 0: pass
+        elif 0: pass
+        else: pass
+
+    def testWhile(self):
+        # 'while' test ':' suite ['else' ':' suite]
+        while 0: pass
+        while 0: pass
+        else: pass
+
+        # Issue1920: "while 0" is optimized away,
+        # ensure that the "else" clause is still present.
+        x = 0
+        while 0:
+            x = 1
+        else:
+            x = 2
+        self.assertEquals(x, 2)
+
+    def testFor(self):
+        # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
+        for i in 1, 2, 3: pass
+        for i, j, k in (): pass
+        else: pass
+        class Squares:
+            def __init__(self, max):
+                self.max = max
+                self.sofar = []
+            def __len__(self): return len(self.sofar)
+            def __getitem__(self, i):
+                if not 0 <= i < self.max: raise IndexError
+                n = len(self.sofar)
+                while n <= i:
+                    self.sofar.append(n*n)
+                    n = n+1
+                return self.sofar[i]
+        n = 0
+        for x in Squares(10): n = n+x
+        if n != 285:
+            self.fail('for over growing sequence')
+
+        result = []
+        for x, in [(1,), (2,), (3,)]:
+            result.append(x)
+        self.assertEqual(result, [1, 2, 3])
+
+    def testTry(self):
+        ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
+        ###         | 'try' ':' suite 'finally' ':' suite
+        ### except_clause: 'except' [expr [('as' | ',') expr]]
+        try:
+            1/0
+        except ZeroDivisionError:
+            pass
+        else:
+            pass
+        try: 1/0
+        except EOFError: pass
+        except TypeError as msg: pass
+        except RuntimeError as msg: pass
+        except: pass
+        else: pass
+        try: 1/0
+        except (EOFError, TypeError, ZeroDivisionError): pass
+        try: 1/0
+        except (EOFError, TypeError, ZeroDivisionError) as msg: pass
+        try: pass
+        finally: pass
+
+    def testSuite(self):
+        # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
+        if 1: pass
+        if 1:
+            pass
+        if 1:
+            #
+            #
+            #
+            pass
+            pass
+            #
+            pass
+            #
+
+    def testTest(self):
+        ### and_test ('or' and_test)*
+        ### and_test: not_test ('and' not_test)*
+        ### not_test: 'not' not_test | comparison
+        if not 1: pass
+        if 1 and 1: pass
+        if 1 or 1: pass
+        if not not not 1: pass
+        if not 1 and 1 and 1: pass
+        if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass
+
+    def testComparison(self):
+        ### comparison: expr (comp_op expr)*
+        ### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+        if 1: pass
+        x = (1 == 1)
+        if 1 == 1: pass
+        if 1 != 1: pass
+        if 1 != 1: pass
+        if 1 < 1: pass
+        if 1 > 1: pass
+        if 1 <= 1: pass
+        if 1 >= 1: pass
+        if 1 is 1: pass
+        if 1 is not 1: pass
+        if 1 in (): pass
+        if 1 not in (): pass
+        if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 != 1 in 1 not in 1 is 1 is not 1: pass
+
+    def testBinaryMaskOps(self):
+        x = 1 & 1
+        x = 1 ^ 1
+        x = 1 | 1
+
+    def testShiftOps(self):
+        x = 1 << 1
+        x = 1 >> 1
+        x = 1 << 1 >> 1
+
+    def testAdditiveOps(self):
+        x = 1
+        x = 1 + 1
+        x = 1 - 1 - 1
+        x = 1 - 1 + 1 - 1 + 1
+
+    def testMultiplicativeOps(self):
+        x = 1 * 1
+        x = 1 / 1
+        x = 1 % 1
+        x = 1 / 1 * 1 % 1
+
+    def testUnaryOps(self):
+        x = +1
+        x = -1
+        x = ~1
+        x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
+        x = -1*1/1 + 1*1 - ---1*1
+
+    def testSelectors(self):
+        ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
+        ### subscript: expr | [expr] ':' [expr]
+
+        import sys, time
+        c = sys.path[0]
+        x = time.time()
+        x = sys.modules['time'].time()
+        a = '01234'
+        c = a[0]
+        c = a[-1]
+        s = a[0:5]
+        s = a[:5]
+        s = a[0:]
+        s = a[:]
+        s = a[-5:]
+        s = a[:-1]
+        s = a[-4:-3]
+        # A rough test of SF bug 1333982.  http://python.org/sf/1333982
+        # The testing here is fairly incomplete.
+        # Test cases should include: commas with 1 and 2 colons
+        d = {}
+        d[1] = 1
+        d[1,] = 2
+        d[1,2] = 3
+        d[1,2,3] = 4
+        L = list(d)
+        L.sort()
+        self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]')
+
+    def testAtoms(self):
+        ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING
+        ### dictmaker: test ':' test (',' test ':' test)* [',']
+
+        x = (1)
+        x = (1 or 2 or 3)
+        x = (1 or 2 or 3, 2, 3)
+
+        x = []
+        x = [1]
+        x = [1 or 2 or 3]
+        x = [1 or 2 or 3, 2, 3]
+        x = []
+
+        x = {}
+        x = {'one': 1}
+        x = {'one': 1,}
+        x = {'one' or 'two': 1 or 2}
+        x = {'one': 1, 'two': 2}
+        x = {'one': 1, 'two': 2,}
+        x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
+
+        x = repr(x)
+        x = repr(1 or 2 or 3)
+        self.assertEqual(repr((1,2)), '(1, 2)')
+
+        x = x
+        x = 'x'
+        x = 123
+
+    ### exprlist: expr (',' expr)* [',']
+    ### testlist: test (',' test)* [',']
+    # These have been exercised enough above
+
+    def testClassdef(self):
+        # 'class' NAME ['(' [testlist] ')'] ':' suite
+        class B: pass
+        class B2(): pass
+        class C1(B): pass
+        class C2(B): pass
+        class D(C1, C2, B): pass
+        class C:
+            def meth1(self): pass
+            def meth2(self, arg): pass
+            def meth3(self, a1, a2): pass
+        # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+        # decorators: decorator+
+        # decorated: decorators (classdef | funcdef)
+        def class_decorator(x):
+            x.decorated = True
+            return x
+        @class_decorator
+        class G:
+            pass
+        self.assertEqual(G.decorated, True)
+
+    def testListcomps(self):
+        # list comprehension tests
+        nums = [1, 2, 3, 4, 5]
+        strs = ["Apple", "Banana", "Coconut"]
+        spcs = ["  Apple", " Banana ", "Coco  nut  "]
+
+        self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco  nut'])
+        self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15])
+        self.assertEqual([x for x in nums if x > 2], [3, 4, 5])
+        self.assertEqual([(i, s) for i in nums for s in strs],
+                         [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'),
+                          (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'),
+                          (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'),
+                          (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'),
+                          (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')])
+        self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]],
+                         [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'),
+                          (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'),
+                          (5, 'Banana'), (5, 'Coconut')])
+        self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)],
+                         [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]])
+
+        def test_in_func(l):
+            return [None < x < 3 for x in l if x > 2]
+
+        self.assertEqual(test_in_func(nums), [False, False, False])
+
+        def test_nested_front():
+            self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]],
+                             [[1, 2], [3, 4], [5, 6]])
+
+        test_nested_front()
+
+        check_syntax_error(self, "[i, s for i in nums for s in strs]")
+        check_syntax_error(self, "[x if y]")
+
+        suppliers = [
+          (1, "Boeing"),
+          (2, "Ford"),
+          (3, "Macdonalds")
+        ]
+
+        parts = [
+          (10, "Airliner"),
+          (20, "Engine"),
+          (30, "Cheeseburger")
+        ]
+
+        suppart = [
+          (1, 10), (1, 20), (2, 20), (3, 30)
+        ]
+
+        x = [
+          (sname, pname)
+            for (sno, sname) in suppliers
+              for (pno, pname) in parts
+                for (sp_sno, sp_pno) in suppart
+                  if sno == sp_sno and pno == sp_pno
+        ]
+
+        self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'),
+                             ('Macdonalds', 'Cheeseburger')])
+
+    def testGenexps(self):
+        # generator expression tests
+        g = ([x for x in range(10)] for x in range(1))
+        self.assertEqual(next(g), [x for x in range(10)])
+        try:
+            next(g)
+            self.fail('should produce StopIteration exception')
+        except StopIteration:
+            pass
+
+        a = 1
+        try:
+            g = (a for d in a)
+            next(g)
+            self.fail('should produce TypeError')
+        except TypeError:
+            pass
+
+        self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd'])
+        self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy'])
+
+        a = [x for x in range(10)]
+        b = (x for x in (y for y in a))
+        self.assertEqual(sum(b), sum([x for x in range(10)]))
+
+        self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)]))
+        self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2]))
+        self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)]))
+        self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)]))
+        self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)]))
+        self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)]))
+        self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0)
+        check_syntax_error(self, "foo(x for x in range(10), 100)")
+        check_syntax_error(self, "foo(100, x for x in range(10))")
+
+    def testComprehensionSpecials(self):
+        # test for outmost iterable precomputation
+        x = 10; g = (i for i in range(x)); x = 5
+        self.assertEqual(len(list(g)), 10)
+
+        # This should hold, since we're only precomputing outmost iterable.
+        x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x))
+        x = 5; t = True;
+        self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g))
+
+        # Grammar allows multiple adjacent 'if's in listcomps and genexps,
+        # even though it's silly. Make sure it works (ifelse broke this.)
+        self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7])
+        self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7])
+
+        # verify unpacking single element tuples in listcomp/genexp.
+        self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6])
+        self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9])
+
+    def test_with_statement(self):
+        class manager(object):
+            def __enter__(self):
+                return (1, 2)
+            def __exit__(self, *args):
+                pass
+
+        with manager():
+            pass
+        with manager() as x:
+            pass
+        with manager() as (x, y):
+            pass
+        with manager(), manager():
+            pass
+        with manager() as x, manager() as y:
+            pass
+        with manager() as x, manager():
+            pass
+
+    def testIfElseExpr(self):
+        # Test ifelse expressions in various cases
+        def _checkeval(msg, ret):
+            "helper to check that evaluation of expressions is done correctly"
+            print(x)
+            return ret
+
+        self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True])
+        self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True])
+        self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True])
+        self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5)
+        self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5)
+        self.assertEqual((5 and 6 if 0 else 1), 1)
+        self.assertEqual(((5 and 6) if 0 else 1), 1)
+        self.assertEqual((5 and (6 if 1 else 1)), 6)
+        self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3)
+        self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1)
+        self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5)
+        self.assertEqual((not 5 if 1 else 1), False)
+        self.assertEqual((not 5 if 0 else 1), 1)
+        self.assertEqual((6 + 1 if 1 else 2), 7)
+        self.assertEqual((6 - 1 if 1 else 2), 5)
+        self.assertEqual((6 * 2 if 1 else 4), 12)
+        self.assertEqual((6 / 2 if 1 else 3), 3)
+        self.assertEqual((6 < 4 if 0 else 2), 2)
+
+
+def test_main():
+    run_unittest(TokenTests, GrammarTests)
+
+if __name__ == '__main__':
+    test_main()
diff --git a/lib3/2to3/lib2to3/tests/data/py3_test_grammar.py b/lib3/2to3/lib2to3/tests/data/py3_test_grammar.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/data/py3_test_grammar.py
@@ -0,0 +1,923 @@
+# Python test set -- part 1, grammar.
+# This just tests whether the parser accepts them all.
+
+# NOTE: When you run this test as a script from the command line, you
+# get warnings about certain hex/oct constants.  Since those are
+# issued by the parser, you can't suppress them by adding a
+# filterwarnings() call to this module.  Therefore, to shut up the
+# regression test, the filterwarnings() call has been added to
+# regrtest.py.
+
+from test.support import run_unittest, check_syntax_error
+import unittest
+import sys
+# testing import *
+from sys import *
+
+class TokenTests(unittest.TestCase):
+
+    def testBackslash(self):
+        # Backslash means line continuation:
+        x = 1 \
+        + 1
+        self.assertEquals(x, 2, 'backslash for line continuation')
+
+        # Backslash does not means continuation in comments :\
+        x = 0
+        self.assertEquals(x, 0, 'backslash ending comment')
+
+    def testPlainIntegers(self):
+        self.assertEquals(type(000), type(0))
+        self.assertEquals(0xff, 255)
+        self.assertEquals(0o377, 255)
+        self.assertEquals(2147483647, 0o17777777777)
+        self.assertEquals(0b1001, 9)
+        # "0x" is not a valid literal
+        self.assertRaises(SyntaxError, eval, "0x")
+        from sys import maxsize
+        if maxsize == 2147483647:
+            self.assertEquals(-2147483647-1, -0o20000000000)
+            # XXX -2147483648
+            self.assert_(0o37777777777 > 0)
+            self.assert_(0xffffffff > 0)
+            self.assert_(0b1111111111111111111111111111111 > 0)
+            for s in ('2147483648', '0o40000000000', '0x100000000',
+                      '0b10000000000000000000000000000000'):
+                try:
+                    x = eval(s)
+                except OverflowError:
+                    self.fail("OverflowError on huge integer literal %r" % s)
+        elif maxsize == 9223372036854775807:
+            self.assertEquals(-9223372036854775807-1, -0o1000000000000000000000)
+            self.assert_(0o1777777777777777777777 > 0)
+            self.assert_(0xffffffffffffffff > 0)
+            self.assert_(0b11111111111111111111111111111111111111111111111111111111111111 > 0)
+            for s in '9223372036854775808', '0o2000000000000000000000', \
+                     '0x10000000000000000', \
+                     '0b100000000000000000000000000000000000000000000000000000000000000':
+                try:
+                    x = eval(s)
+                except OverflowError:
+                    self.fail("OverflowError on huge integer literal %r" % s)
+        else:
+            self.fail('Weird maxsize value %r' % maxsize)
+
+    def testLongIntegers(self):
+        x = 0
+        x = 0xffffffffffffffff
+        x = 0Xffffffffffffffff
+        x = 0o77777777777777777
+        x = 0O77777777777777777
+        x = 123456789012345678901234567890
+        x = 0b100000000000000000000000000000000000000000000000000000000000000000000
+        x = 0B111111111111111111111111111111111111111111111111111111111111111111111
+
+    def testFloats(self):
+        x = 3.14
+        x = 314.
+        x = 0.314
+        # XXX x = 000.314
+        x = .314
+        x = 3e14
+        x = 3E14
+        x = 3e-14
+        x = 3e+14
+        x = 3.e14
+        x = .3e14
+        x = 3.1e4
+
+    def testStringLiterals(self):
+        x = ''; y = ""; self.assert_(len(x) == 0 and x == y)
+        x = '\''; y = "'"; self.assert_(len(x) == 1 and x == y and ord(x) == 39)
+        x = '"'; y = "\""; self.assert_(len(x) == 1 and x == y and ord(x) == 34)
+        x = "doesn't \"shrink\" does it"
+        y = 'doesn\'t "shrink" does it'
+        self.assert_(len(x) == 24 and x == y)
+        x = "does \"shrink\" doesn't it"
+        y = 'does "shrink" doesn\'t it'
+        self.assert_(len(x) == 24 and x == y)
+        x = """
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+"""
+        y = '\nThe "quick"\nbrown fox\njumps over\nthe \'lazy\' dog.\n'
+        self.assertEquals(x, y)
+        y = '''
+The "quick"
+brown fox
+jumps over
+the 'lazy' dog.
+'''
+        self.assertEquals(x, y)
+        y = "\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the 'lazy' dog.\n\
+"
+        self.assertEquals(x, y)
+        y = '\n\
+The \"quick\"\n\
+brown fox\n\
+jumps over\n\
+the \'lazy\' dog.\n\
+'
+        self.assertEquals(x, y)
+
+    def testEllipsis(self):
+        x = ...
+        self.assert_(x is Ellipsis)
+        self.assertRaises(SyntaxError, eval, ".. .")
+
+class GrammarTests(unittest.TestCase):
+
+    # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
+    # XXX can't test in a script -- this rule is only used when interactive
+
+    # file_input: (NEWLINE | stmt)* ENDMARKER
+    # Being tested as this very moment this very module
+
+    # expr_input: testlist NEWLINE
+    # XXX Hard to test -- used only in calls to input()
+
+    def testEvalInput(self):
+        # testlist ENDMARKER
+        x = eval('1, 0 or 1')
+
+    def testFuncdef(self):
+        ### [decorators] 'def' NAME parameters ['->' test] ':' suite
+        ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+        ### decorators: decorator+
+        ### parameters: '(' [typedargslist] ')'
+        ### typedargslist: ((tfpdef ['=' test] ',')*
+        ###                ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef)
+        ###                | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
+        ### tfpdef: NAME [':' test]
+        ### varargslist: ((vfpdef ['=' test] ',')*
+        ###              ('*' [vfpdef] (',' vfpdef ['=' test])*  [',' '**' vfpdef] | '**' vfpdef)
+        ###              | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+        ### vfpdef: NAME
+        def f1(): pass
+        f1()
+        f1(*())
+        f1(*(), **{})
+        def f2(one_argument): pass
+        def f3(two, arguments): pass
+        self.assertEquals(f2.__code__.co_varnames, ('one_argument',))
+        self.assertEquals(f3.__code__.co_varnames, ('two', 'arguments'))
+        def a1(one_arg,): pass
+        def a2(two, args,): pass
+        def v0(*rest): pass
+        def v1(a, *rest): pass
+        def v2(a, b, *rest): pass
+
+        f1()
+        f2(1)
+        f2(1,)
+        f3(1, 2)
+        f3(1, 2,)
+        v0()
+        v0(1)
+        v0(1,)
+        v0(1,2)
+        v0(1,2,3,4,5,6,7,8,9,0)
+        v1(1)
+        v1(1,)
+        v1(1,2)
+        v1(1,2,3)
+        v1(1,2,3,4,5,6,7,8,9,0)
+        v2(1,2)
+        v2(1,2,3)
+        v2(1,2,3,4)
+        v2(1,2,3,4,5,6,7,8,9,0)
+
+        def d01(a=1): pass
+        d01()
+        d01(1)
+        d01(*(1,))
+        d01(**{'a':2})
+        def d11(a, b=1): pass
+        d11(1)
+        d11(1, 2)
+        d11(1, **{'b':2})
+        def d21(a, b, c=1): pass
+        d21(1, 2)
+        d21(1, 2, 3)
+        d21(*(1, 2, 3))
+        d21(1, *(2, 3))
+        d21(1, 2, *(3,))
+        d21(1, 2, **{'c':3})
+        def d02(a=1, b=2): pass
+        d02()
+        d02(1)
+        d02(1, 2)
+        d02(*(1, 2))
+        d02(1, *(2,))
+        d02(1, **{'b':2})
+        d02(**{'a': 1, 'b': 2})
+        def d12(a, b=1, c=2): pass
+        d12(1)
+        d12(1, 2)
+        d12(1, 2, 3)
+        def d22(a, b, c=1, d=2): pass
+        d22(1, 2)
+        d22(1, 2, 3)
+        d22(1, 2, 3, 4)
+        def d01v(a=1, *rest): pass
+        d01v()
+        d01v(1)
+        d01v(1, 2)
+        d01v(*(1, 2, 3, 4))
+        d01v(*(1,))
+        d01v(**{'a':2})
+        def d11v(a, b=1, *rest): pass
+        d11v(1)
+        d11v(1, 2)
+        d11v(1, 2, 3)
+        def d21v(a, b, c=1, *rest): pass
+        d21v(1, 2)
+        d21v(1, 2, 3)
+        d21v(1, 2, 3, 4)
+        d21v(*(1, 2, 3, 4))
+        d21v(1, 2, **{'c': 3})
+        def d02v(a=1, b=2, *rest): pass
+        d02v()
+        d02v(1)
+        d02v(1, 2)
+        d02v(1, 2, 3)
+        d02v(1, *(2, 3, 4))
+        d02v(**{'a': 1, 'b': 2})
+        def d12v(a, b=1, c=2, *rest): pass
+        d12v(1)
+        d12v(1, 2)
+        d12v(1, 2, 3)
+        d12v(1, 2, 3, 4)
+        d12v(*(1, 2, 3, 4))
+        d12v(1, 2, *(3, 4, 5))
+        d12v(1, *(2,), **{'c': 3})
+        def d22v(a, b, c=1, d=2, *rest): pass
+        d22v(1, 2)
+        d22v(1, 2, 3)
+        d22v(1, 2, 3, 4)
+        d22v(1, 2, 3, 4, 5)
+        d22v(*(1, 2, 3, 4))
+        d22v(1, 2, *(3, 4, 5))
+        d22v(1, *(2, 3), **{'d': 4})
+
+        # keyword argument type tests
+        try:
+            str('x', **{b'foo':1 })
+        except TypeError:
+            pass
+        else:
+            self.fail('Bytes should not work as keyword argument names')
+        # keyword only argument tests
+        def pos0key1(*, key): return key
+        pos0key1(key=100)
+        def pos2key2(p1, p2, *, k1, k2=100): return p1,p2,k1,k2
+        pos2key2(1, 2, k1=100)
+        pos2key2(1, 2, k1=100, k2=200)
+        pos2key2(1, 2, k2=100, k1=200)
+        def pos2key2dict(p1, p2, *, k1=100, k2, **kwarg): return p1,p2,k1,k2,kwarg
+        pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200)
+        pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100)
+
+        # keyword arguments after *arglist
+        def f(*args, **kwargs):
+            return args, kwargs
+        self.assertEquals(f(1, x=2, *[3, 4], y=5), ((1, 3, 4),
+                                                    {'x':2, 'y':5}))
+        self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)")
+        self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)")
+
+        # argument annotation tests
+        def f(x) -> list: pass
+        self.assertEquals(f.__annotations__, {'return': list})
+        def f(x:int): pass
+        self.assertEquals(f.__annotations__, {'x': int})
+        def f(*x:str): pass
+        self.assertEquals(f.__annotations__, {'x': str})
+        def f(**x:float): pass
+        self.assertEquals(f.__annotations__, {'x': float})
+        def f(x, y:1+2): pass
+        self.assertEquals(f.__annotations__, {'y': 3})
+        def f(a, b:1, c:2, d): pass
+        self.assertEquals(f.__annotations__, {'b': 1, 'c': 2})
+        def f(a, b:1, c:2, d, e:3=4, f=5, *g:6): pass
+        self.assertEquals(f.__annotations__,
+                          {'b': 1, 'c': 2, 'e': 3, 'g': 6})
+        def f(a, b:1, c:2, d, e:3=4, f=5, *g:6, h:7, i=8, j:9=10,
+              **k:11) -> 12: pass
+        self.assertEquals(f.__annotations__,
+                          {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9,
+                           'k': 11, 'return': 12})
+        # Check for SF Bug #1697248 - mixing decorators and a return annotation
+        def null(x): return x
+        @null
+        def f(x) -> list: pass
+        self.assertEquals(f.__annotations__, {'return': list})
+
+        # test MAKE_CLOSURE with a variety of oparg's
+        closure = 1
+        def f(): return closure
+        def f(x=1): return closure
+        def f(*, k=1): return closure
+        def f() -> int: return closure
+
+        # Check ast errors in *args and *kwargs
+        check_syntax_error(self, "f(*g(1=2))")
+        check_syntax_error(self, "f(**g(1=2))")
+
+    def testLambdef(self):
+        ### lambdef: 'lambda' [varargslist] ':' test
+        l1 = lambda : 0
+        self.assertEquals(l1(), 0)
+        l2 = lambda : a[d] # XXX just testing the expression
+        l3 = lambda : [2 < x for x in [-1, 3, 0]]
+        self.assertEquals(l3(), [0, 1, 0])
+        l4 = lambda x = lambda y = lambda z=1 : z : y() : x()
+        self.assertEquals(l4(), 1)
+        l5 = lambda x, y, z=2: x + y + z
+        self.assertEquals(l5(1, 2), 5)
+        self.assertEquals(l5(1, 2, 3), 6)
+        check_syntax_error(self, "lambda x: x = 2")
+        check_syntax_error(self, "lambda (None,): None")
+        l6 = lambda x, y, *, k=20: x+y+k
+        self.assertEquals(l6(1,2), 1+2+20)
+        self.assertEquals(l6(1,2,k=10), 1+2+10)
+
+
+    ### stmt: simple_stmt | compound_stmt
+    # Tested below
+
+    def testSimpleStmt(self):
+        ### simple_stmt: small_stmt (';' small_stmt)* [';']
+        x = 1; pass; del x
+        def foo():
+            # verify statments that end with semi-colons
+            x = 1; pass; del x;
+        foo()
+
+    ### small_stmt: expr_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt
+    # Tested below
+
+    def testExprStmt(self):
+        # (exprlist '=')* exprlist
+        1
+        1, 2, 3
+        x = 1
+        x = 1, 2, 3
+        x = y = z = 1, 2, 3
+        x, y, z = 1, 2, 3
+        abc = a, b, c = x, y, z = xyz = 1, 2, (3, 4)
+
+        check_syntax_error(self, "x + 1 = 1")
+        check_syntax_error(self, "a + 1 = b + 2")
+
+    def testDelStmt(self):
+        # 'del' exprlist
+        abc = [1,2,3]
+        x, y, z = abc
+        xyz = x, y, z
+
+        del abc
+        del x, y, (z, xyz)
+
+    def testPassStmt(self):
+        # 'pass'
+        pass
+
+    # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt
+    # Tested below
+
+    def testBreakStmt(self):
+        # 'break'
+        while 1: break
+
+    def testContinueStmt(self):
+        # 'continue'
+        i = 1
+        while i: i = 0; continue
+
+        msg = ""
+        while not msg:
+            msg = "ok"
+            try:
+                continue
+                msg = "continue failed to continue inside try"
+            except:
+                msg = "continue inside try called except block"
+        if msg != "ok":
+            self.fail(msg)
+
+        msg = ""
+        while not msg:
+            msg = "finally block not called"
+            try:
+                continue
+            finally:
+                msg = "ok"
+        if msg != "ok":
+            self.fail(msg)
+
+    def test_break_continue_loop(self):
+        # This test warrants an explanation. It is a test specifically for SF bugs
+        # #463359 and #462937. The bug is that a 'break' statement executed or
+        # exception raised inside a try/except inside a loop, *after* a continue
+        # statement has been executed in that loop, will cause the wrong number of
+        # arguments to be popped off the stack and the instruction pointer reset to
+        # a very small number (usually 0.) Because of this, the following test
+        # *must* written as a function, and the tracking vars *must* be function
+        # arguments with default values. Otherwise, the test will loop and loop.
+
+        def test_inner(extra_burning_oil = 1, count=0):
+            big_hippo = 2
+            while big_hippo:
+                count += 1
+                try:
+                    if extra_burning_oil and big_hippo == 1:
+                        extra_burning_oil -= 1
+                        break
+                    big_hippo -= 1
+                    continue
+                except:
+                    raise
+            if count > 2 or big_hippo != 1:
+                self.fail("continue then break in try/except in loop broken!")
+        test_inner()
+
+    def testReturn(self):
+        # 'return' [testlist]
+        def g1(): return
+        def g2(): return 1
+        g1()
+        x = g2()
+        check_syntax_error(self, "class foo:return 1")
+
+    def testYield(self):
+        check_syntax_error(self, "class foo:yield 1")
+
+    def testRaise(self):
+        # 'raise' test [',' test]
+        try: raise RuntimeError('just testing')
+        except RuntimeError: pass
+        try: raise KeyboardInterrupt
+        except KeyboardInterrupt: pass
+
+    def testImport(self):
+        # 'import' dotted_as_names
+        import sys
+        import time, sys
+        # 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names)
+        from time import time
+        from time import (time)
+        # not testable inside a function, but already done at top of the module
+        # from sys import *
+        from sys import path, argv
+        from sys import (path, argv)
+        from sys import (path, argv,)
+
+    def testGlobal(self):
+        # 'global' NAME (',' NAME)*
+        global a
+        global a, b
+        global one, two, three, four, five, six, seven, eight, nine, ten
+
+    def testNonlocal(self):
+        # 'nonlocal' NAME (',' NAME)*
+        x = 0
+        y = 0
+        def f():
+            nonlocal x
+            nonlocal x, y
+
+    def testAssert(self):
+        # assert_stmt: 'assert' test [',' test]
+        assert 1
+        assert 1, 1
+        assert lambda x:x
+        assert 1, lambda x:x+1
+        try:
+            assert 0, "msg"
+        except AssertionError as e:
+            self.assertEquals(e.args[0], "msg")
+        else:
+            if __debug__:
+                self.fail("AssertionError not raised by assert 0")
+
+    ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
+    # Tested below
+
+    def testIf(self):
+        # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
+        if 1: pass
+        if 1: pass
+        else: pass
+        if 0: pass
+        elif 0: pass
+        if 0: pass
+        elif 0: pass
+        elif 0: pass
+        elif 0: pass
+        else: pass
+
+    def testWhile(self):
+        # 'while' test ':' suite ['else' ':' suite]
+        while 0: pass
+        while 0: pass
+        else: pass
+
+        # Issue1920: "while 0" is optimized away,
+        # ensure that the "else" clause is still present.
+        x = 0
+        while 0:
+            x = 1
+        else:
+            x = 2
+        self.assertEquals(x, 2)
+
+    def testFor(self):
+        # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
+        for i in 1, 2, 3: pass
+        for i, j, k in (): pass
+        else: pass
+        class Squares:
+            def __init__(self, max):
+                self.max = max
+                self.sofar = []
+            def __len__(self): return len(self.sofar)
+            def __getitem__(self, i):
+                if not 0 <= i < self.max: raise IndexError
+                n = len(self.sofar)
+                while n <= i:
+                    self.sofar.append(n*n)
+                    n = n+1
+                return self.sofar[i]
+        n = 0
+        for x in Squares(10): n = n+x
+        if n != 285:
+            self.fail('for over growing sequence')
+
+        result = []
+        for x, in [(1,), (2,), (3,)]:
+            result.append(x)
+        self.assertEqual(result, [1, 2, 3])
+
+    def testTry(self):
+        ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
+        ###         | 'try' ':' suite 'finally' ':' suite
+        ### except_clause: 'except' [expr ['as' expr]]
+        try:
+            1/0
+        except ZeroDivisionError:
+            pass
+        else:
+            pass
+        try: 1/0
+        except EOFError: pass
+        except TypeError as msg: pass
+        except RuntimeError as msg: pass
+        except: pass
+        else: pass
+        try: 1/0
+        except (EOFError, TypeError, ZeroDivisionError): pass
+        try: 1/0
+        except (EOFError, TypeError, ZeroDivisionError) as msg: pass
+        try: pass
+        finally: pass
+
+    def testSuite(self):
+        # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
+        if 1: pass
+        if 1:
+            pass
+        if 1:
+            #
+            #
+            #
+            pass
+            pass
+            #
+            pass
+            #
+
+    def testTest(self):
+        ### and_test ('or' and_test)*
+        ### and_test: not_test ('and' not_test)*
+        ### not_test: 'not' not_test | comparison
+        if not 1: pass
+        if 1 and 1: pass
+        if 1 or 1: pass
+        if not not not 1: pass
+        if not 1 and 1 and 1: pass
+        if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass
+
+    def testComparison(self):
+        ### comparison: expr (comp_op expr)*
+        ### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+        if 1: pass
+        x = (1 == 1)
+        if 1 == 1: pass
+        if 1 != 1: pass
+        if 1 < 1: pass
+        if 1 > 1: pass
+        if 1 <= 1: pass
+        if 1 >= 1: pass
+        if 1 is 1: pass
+        if 1 is not 1: pass
+        if 1 in (): pass
+        if 1 not in (): pass
+        if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass
+
+    def testBinaryMaskOps(self):
+        x = 1 & 1
+        x = 1 ^ 1
+        x = 1 | 1
+
+    def testShiftOps(self):
+        x = 1 << 1
+        x = 1 >> 1
+        x = 1 << 1 >> 1
+
+    def testAdditiveOps(self):
+        x = 1
+        x = 1 + 1
+        x = 1 - 1 - 1
+        x = 1 - 1 + 1 - 1 + 1
+
+    def testMultiplicativeOps(self):
+        x = 1 * 1
+        x = 1 / 1
+        x = 1 % 1
+        x = 1 / 1 * 1 % 1
+
+    def testUnaryOps(self):
+        x = +1
+        x = -1
+        x = ~1
+        x = ~1 ^ 1 & 1 | 1 & 1 ^ -1
+        x = -1*1/1 + 1*1 - ---1*1
+
+    def testSelectors(self):
+        ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
+        ### subscript: expr | [expr] ':' [expr]
+
+        import sys, time
+        c = sys.path[0]
+        x = time.time()
+        x = sys.modules['time'].time()
+        a = '01234'
+        c = a[0]
+        c = a[-1]
+        s = a[0:5]
+        s = a[:5]
+        s = a[0:]
+        s = a[:]
+        s = a[-5:]
+        s = a[:-1]
+        s = a[-4:-3]
+        # A rough test of SF bug 1333982.  http://python.org/sf/1333982
+        # The testing here is fairly incomplete.
+        # Test cases should include: commas with 1 and 2 colons
+        d = {}
+        d[1] = 1
+        d[1,] = 2
+        d[1,2] = 3
+        d[1,2,3] = 4
+        L = list(d)
+        L.sort(key=lambda x: x if isinstance(x, tuple) else ())
+        self.assertEquals(str(L), '[1, (1,), (1, 2), (1, 2, 3)]')
+
+    def testAtoms(self):
+        ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING
+        ### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [','])
+
+        x = (1)
+        x = (1 or 2 or 3)
+        x = (1 or 2 or 3, 2, 3)
+
+        x = []
+        x = [1]
+        x = [1 or 2 or 3]
+        x = [1 or 2 or 3, 2, 3]
+        x = []
+
+        x = {}
+        x = {'one': 1}
+        x = {'one': 1,}
+        x = {'one' or 'two': 1 or 2}
+        x = {'one': 1, 'two': 2}
+        x = {'one': 1, 'two': 2,}
+        x = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6}
+
+        x = {'one'}
+        x = {'one', 1,}
+        x = {'one', 'two', 'three'}
+        x = {2, 3, 4,}
+
+        x = x
+        x = 'x'
+        x = 123
+
+    ### exprlist: expr (',' expr)* [',']
+    ### testlist: test (',' test)* [',']
+    # These have been exercised enough above
+
+    def testClassdef(self):
+        # 'class' NAME ['(' [testlist] ')'] ':' suite
+        class B: pass
+        class B2(): pass
+        class C1(B): pass
+        class C2(B): pass
+        class D(C1, C2, B): pass
+        class C:
+            def meth1(self): pass
+            def meth2(self, arg): pass
+            def meth3(self, a1, a2): pass
+
+        # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+        # decorators: decorator+
+        # decorated: decorators (classdef | funcdef)
+        def class_decorator(x): return x
+        @class_decorator
+        class G: pass
+
+    def testDictcomps(self):
+        # dictorsetmaker: ( (test ':' test (comp_for |
+        #                                   (',' test ':' test)* [','])) |
+        #                   (test (comp_for | (',' test)* [','])) )
+        nums = [1, 2, 3]
+        self.assertEqual({i:i+1 for i in nums}, {1: 2, 2: 3, 3: 4})
+
+    def testListcomps(self):
+        # list comprehension tests
+        nums = [1, 2, 3, 4, 5]
+        strs = ["Apple", "Banana", "Coconut"]
+        spcs = ["  Apple", " Banana ", "Coco  nut  "]
+
+        self.assertEqual([s.strip() for s in spcs], ['Apple', 'Banana', 'Coco  nut'])
+        self.assertEqual([3 * x for x in nums], [3, 6, 9, 12, 15])
+        self.assertEqual([x for x in nums if x > 2], [3, 4, 5])
+        self.assertEqual([(i, s) for i in nums for s in strs],
+                         [(1, 'Apple'), (1, 'Banana'), (1, 'Coconut'),
+                          (2, 'Apple'), (2, 'Banana'), (2, 'Coconut'),
+                          (3, 'Apple'), (3, 'Banana'), (3, 'Coconut'),
+                          (4, 'Apple'), (4, 'Banana'), (4, 'Coconut'),
+                          (5, 'Apple'), (5, 'Banana'), (5, 'Coconut')])
+        self.assertEqual([(i, s) for i in nums for s in [f for f in strs if "n" in f]],
+                         [(1, 'Banana'), (1, 'Coconut'), (2, 'Banana'), (2, 'Coconut'),
+                          (3, 'Banana'), (3, 'Coconut'), (4, 'Banana'), (4, 'Coconut'),
+                          (5, 'Banana'), (5, 'Coconut')])
+        self.assertEqual([(lambda a:[a**i for i in range(a+1)])(j) for j in range(5)],
+                         [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]])
+
+        def test_in_func(l):
+            return [0 < x < 3 for x in l if x > 2]
+
+        self.assertEqual(test_in_func(nums), [False, False, False])
+
+        def test_nested_front():
+            self.assertEqual([[y for y in [x, x + 1]] for x in [1,3,5]],
+                             [[1, 2], [3, 4], [5, 6]])
+
+        test_nested_front()
+
+        check_syntax_error(self, "[i, s for i in nums for s in strs]")
+        check_syntax_error(self, "[x if y]")
+
+        suppliers = [
+          (1, "Boeing"),
+          (2, "Ford"),
+          (3, "Macdonalds")
+        ]
+
+        parts = [
+          (10, "Airliner"),
+          (20, "Engine"),
+          (30, "Cheeseburger")
+        ]
+
+        suppart = [
+          (1, 10), (1, 20), (2, 20), (3, 30)
+        ]
+
+        x = [
+          (sname, pname)
+            for (sno, sname) in suppliers
+              for (pno, pname) in parts
+                for (sp_sno, sp_pno) in suppart
+                  if sno == sp_sno and pno == sp_pno
+        ]
+
+        self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'),
+                             ('Macdonalds', 'Cheeseburger')])
+
+    def testGenexps(self):
+        # generator expression tests
+        g = ([x for x in range(10)] for x in range(1))
+        self.assertEqual(next(g), [x for x in range(10)])
+        try:
+            next(g)
+            self.fail('should produce StopIteration exception')
+        except StopIteration:
+            pass
+
+        a = 1
+        try:
+            g = (a for d in a)
+            next(g)
+            self.fail('should produce TypeError')
+        except TypeError:
+            pass
+
+        self.assertEqual(list((x, y) for x in 'abcd' for y in 'abcd'), [(x, y) for x in 'abcd' for y in 'abcd'])
+        self.assertEqual(list((x, y) for x in 'ab' for y in 'xy'), [(x, y) for x in 'ab' for y in 'xy'])
+
+        a = [x for x in range(10)]
+        b = (x for x in (y for y in a))
+        self.assertEqual(sum(b), sum([x for x in range(10)]))
+
+        self.assertEqual(sum(x**2 for x in range(10)), sum([x**2 for x in range(10)]))
+        self.assertEqual(sum(x*x for x in range(10) if x%2), sum([x*x for x in range(10) if x%2]))
+        self.assertEqual(sum(x for x in (y for y in range(10))), sum([x for x in range(10)]))
+        self.assertEqual(sum(x for x in (y for y in (z for z in range(10)))), sum([x for x in range(10)]))
+        self.assertEqual(sum(x for x in [y for y in (z for z in range(10))]), sum([x for x in range(10)]))
+        self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True)) if True), sum([x for x in range(10)]))
+        self.assertEqual(sum(x for x in (y for y in (z for z in range(10) if True) if False) if True), 0)
+        check_syntax_error(self, "foo(x for x in range(10), 100)")
+        check_syntax_error(self, "foo(100, x for x in range(10))")
+
+    def testComprehensionSpecials(self):
+        # test for outmost iterable precomputation
+        x = 10; g = (i for i in range(x)); x = 5
+        self.assertEqual(len(list(g)), 10)
+
+        # This should hold, since we're only precomputing outmost iterable.
+        x = 10; t = False; g = ((i,j) for i in range(x) if t for j in range(x))
+        x = 5; t = True;
+        self.assertEqual([(i,j) for i in range(10) for j in range(5)], list(g))
+
+        # Grammar allows multiple adjacent 'if's in listcomps and genexps,
+        # even though it's silly. Make sure it works (ifelse broke this.)
+        self.assertEqual([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7])
+        self.assertEqual(list(x for x in range(10) if x % 2 if x % 3), [1, 5, 7])
+
+        # verify unpacking single element tuples in listcomp/genexp.
+        self.assertEqual([x for x, in [(4,), (5,), (6,)]], [4, 5, 6])
+        self.assertEqual(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9])
+
+    def test_with_statement(self):
+        class manager(object):
+            def __enter__(self):
+                return (1, 2)
+            def __exit__(self, *args):
+                pass
+
+        with manager():
+            pass
+        with manager() as x:
+            pass
+        with manager() as (x, y):
+            pass
+        with manager(), manager():
+            pass
+        with manager() as x, manager() as y:
+            pass
+        with manager() as x, manager():
+            pass
+
+    def testIfElseExpr(self):
+        # Test ifelse expressions in various cases
+        def _checkeval(msg, ret):
+            "helper to check that evaluation of expressions is done correctly"
+            print(x)
+            return ret
+
+        # the next line is not allowed anymore
+        #self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True])
+        self.assertEqual([ x() for x in (lambda: True, lambda: False) if x() ], [True])
+        self.assertEqual([ x(False) for x in (lambda x: False if x else True, lambda x: True if x else False) if x(False) ], [True])
+        self.assertEqual((5 if 1 else _checkeval("check 1", 0)), 5)
+        self.assertEqual((_checkeval("check 2", 0) if 0 else 5), 5)
+        self.assertEqual((5 and 6 if 0 else 1), 1)
+        self.assertEqual(((5 and 6) if 0 else 1), 1)
+        self.assertEqual((5 and (6 if 1 else 1)), 6)
+        self.assertEqual((0 or _checkeval("check 3", 2) if 0 else 3), 3)
+        self.assertEqual((1 or _checkeval("check 4", 2) if 1 else _checkeval("check 5", 3)), 1)
+        self.assertEqual((0 or 5 if 1 else _checkeval("check 6", 3)), 5)
+        self.assertEqual((not 5 if 1 else 1), False)
+        self.assertEqual((not 5 if 0 else 1), 1)
+        self.assertEqual((6 + 1 if 1 else 2), 7)
+        self.assertEqual((6 - 1 if 1 else 2), 5)
+        self.assertEqual((6 * 2 if 1 else 4), 12)
+        self.assertEqual((6 / 2 if 1 else 3), 3)
+        self.assertEqual((6 < 4 if 0 else 2), 2)
+
+
+def test_main():
+    run_unittest(TokenTests, GrammarTests)
+
+if __name__ == '__main__':
+    test_main()
diff --git a/lib3/2to3/lib2to3/tests/pytree_idempotency.py b/lib3/2to3/lib2to3/tests/pytree_idempotency.py
new file mode 100755
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/pytree_idempotency.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Main program for testing the infrastructure."""
+
+__author__ = "Guido van Rossum <guido at python.org>"
+
+# Support imports (need to be imported first)
+from . import support
+
+# Python imports
+import os
+import sys
+import logging
+
+# Local imports
+from .. import pytree
+import pgen2
+from pgen2 import driver
+
+logging.basicConfig()
+
+def main():
+    gr = driver.load_grammar("Grammar.txt")
+    dr = driver.Driver(gr, convert=pytree.convert)
+
+    fn = "example.py"
+    tree = dr.parse_file(fn, debug=True)
+    if not diff(fn, tree):
+        print("No diffs.")
+    if not sys.argv[1:]:
+        return # Pass a dummy argument to run the complete test suite below
+
+    problems = []
+
+    # Process every imported module
+    for name in sys.modules:
+        mod = sys.modules[name]
+        if mod is None or not hasattr(mod, "__file__"):
+            continue
+        fn = mod.__file__
+        if fn.endswith(".pyc"):
+            fn = fn[:-1]
+        if not fn.endswith(".py"):
+            continue
+        print("Parsing", fn, file=sys.stderr)
+        tree = dr.parse_file(fn, debug=True)
+        if diff(fn, tree):
+            problems.append(fn)
+
+    # Process every single module on sys.path (but not in packages)
+    for dir in sys.path:
+        try:
+            names = os.listdir(dir)
+        except os.error:
+            continue
+        print("Scanning", dir, "...", file=sys.stderr)
+        for name in names:
+            if not name.endswith(".py"):
+                continue
+            print("Parsing", name, file=sys.stderr)
+            fn = os.path.join(dir, name)
+            try:
+                tree = dr.parse_file(fn, debug=True)
+            except pgen2.parse.ParseError as err:
+                print("ParseError:", err)
+            else:
+                if diff(fn, tree):
+                    problems.append(fn)
+
+    # Show summary of problem files
+    if not problems:
+        print("No problems.  Congratulations!")
+    else:
+        print("Problems in following files:")
+        for fn in problems:
+            print("***", fn)
+
+def diff(fn, tree):
+    f = open("@", "w")
+    try:
+        f.write(str(tree))
+    finally:
+        f.close()
+    try:
+        return os.system("diff -u %s @" % fn)
+    finally:
+        os.remove("@")
+
+if __name__ == "__main__":
+    main()
diff --git a/lib3/2to3/lib2to3/tests/support.py b/lib3/2to3/lib2to3/tests/support.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/support.py
@@ -0,0 +1,54 @@
+"""Support code for test_*.py files"""
+# Author: Collin Winter
+
+# Python imports
+import unittest
+import sys
+import os
+import os.path
+import re
+from textwrap import dedent
+
+# Local imports
+from lib2to3 import pytree, refactor
+from lib2to3.pgen2 import driver
+
+test_dir = os.path.dirname(__file__)
+proj_dir = os.path.normpath(os.path.join(test_dir, ".."))
+grammar_path = os.path.join(test_dir, "..", "Grammar.txt")
+grammar = driver.load_grammar(grammar_path)
+driver = driver.Driver(grammar, convert=pytree.convert)
+
+def parse_string(string):
+    return driver.parse_string(reformat(string), debug=True)
+
+def run_all_tests(test_mod=None, tests=None):
+    if tests is None:
+        tests = unittest.TestLoader().loadTestsFromModule(test_mod)
+    unittest.TextTestRunner(verbosity=2).run(tests)
+
+def reformat(string):
+    return dedent(string) + "\n\n"
+
+def get_refactorer(fixer_pkg="lib2to3", fixers=None, options=None):
+    """
+    A convenience function for creating a RefactoringTool for tests.
+
+    fixers is a list of fixers for the RefactoringTool to use. By default
+    "lib2to3.fixes.*" is used. options is an optional dictionary of options to
+    be passed to the RefactoringTool.
+    """
+    if fixers is not None:
+        fixers = [fixer_pkg + ".fixes.fix_" + fix for fix in fixers]
+    else:
+        fixers = refactor.get_fixers_from_package(fixer_pkg + ".fixes")
+    options = options or {}
+    return refactor.RefactoringTool(fixers, options, explicit=True)
+
+def all_project_files():
+    for dirpath, dirnames, filenames in os.walk(proj_dir):
+        for filename in filenames:
+            if filename.endswith(".py"):
+                yield os.path.join(dirpath, filename)
+
+TestCase = unittest.TestCase
diff --git a/lib3/2to3/lib2to3/tests/test_all_fixers.py b/lib3/2to3/lib2to3/tests/test_all_fixers.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/test_all_fixers.py
@@ -0,0 +1,23 @@
+"""Tests that run all fixer modules over an input stream.
+
+This has been broken out into its own test module because of its
+running time.
+"""
+# Author: Collin Winter
+
+# Python imports
+import unittest
+
+# Local imports
+from lib2to3 import refactor
+from . import support
+
+
+class Test_all(support.TestCase):
+
+    def setUp(self):
+        self.refactor = support.get_refactorer()
+
+    def test_all_project_files(self):
+        for filepath in support.all_project_files():
+            self.refactor.refactor_file(filepath)
diff --git a/lib3/2to3/lib2to3/tests/test_fixers.py b/lib3/2to3/lib2to3/tests/test_fixers.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/test_fixers.py
@@ -0,0 +1,4515 @@
+""" Test suite for the fixer modules """
+
+# Python imports
+import os
+import unittest
+from itertools import chain
+from operator import itemgetter
+
+# Local imports
+from lib2to3 import pygram, pytree, refactor, fixer_util
+from lib2to3.tests import support
+
+
+class FixerTestCase(support.TestCase):
+
+    # Other test cases can subclass this class and replace "fixer_pkg" with
+    # their own.
+    def setUp(self, fix_list=None, fixer_pkg="lib2to3", options=None):
+        if fix_list is None:
+            fix_list = [self.fixer]
+        self.refactor = support.get_refactorer(fixer_pkg, fix_list, options)
+        self.fixer_log = []
+        self.filename = "<string>"
+
+        for fixer in chain(self.refactor.pre_order,
+                           self.refactor.post_order):
+            fixer.log = self.fixer_log
+
+    def _check(self, before, after):
+        before = support.reformat(before)
+        after = support.reformat(after)
+        tree = self.refactor.refactor_string(before, self.filename)
+        self.assertEqual(after, str(tree))
+        return tree
+
+    def check(self, before, after, ignore_warnings=False):
+        tree = self._check(before, after)
+        self.assertTrue(tree.was_changed)
+        if not ignore_warnings:
+            self.assertEqual(self.fixer_log, [])
+
+    def warns(self, before, after, message, unchanged=False):
+        tree = self._check(before, after)
+        self.assertTrue(message in "".join(self.fixer_log))
+        if not unchanged:
+            self.assertTrue(tree.was_changed)
+
+    def warns_unchanged(self, before, message):
+        self.warns(before, before, message, unchanged=True)
+
+    def unchanged(self, before, ignore_warnings=False):
+        self._check(before, before)
+        if not ignore_warnings:
+            self.assertEqual(self.fixer_log, [])
+
+    def assert_runs_after(self, *names):
+        fixes = [self.fixer]
+        fixes.extend(names)
+        r = support.get_refactorer("lib2to3", fixes)
+        (pre, post) = r.get_fixers()
+        n = "fix_" + self.fixer
+        if post and post[-1].__class__.__module__.endswith(n):
+            # We're the last fixer to run
+            return
+        if pre and pre[-1].__class__.__module__.endswith(n) and not post:
+            # We're the last in pre and post is empty
+            return
+        self.fail("Fixer run order (%s) is incorrect; %s should be last."\
+               %(", ".join([x.__class__.__module__ for x in (pre+post)]), n))
+
+class Test_ne(FixerTestCase):
+    fixer = "ne"
+
+    def test_basic(self):
+        b = """if x <> y:
+            pass"""
+
+        a = """if x != y:
+            pass"""
+        self.check(b, a)
+
+    def test_no_spaces(self):
+        b = """if x<>y:
+            pass"""
+
+        a = """if x!=y:
+            pass"""
+        self.check(b, a)
+
+    def test_chained(self):
+        b = """if x<>y<>z:
+            pass"""
+
+        a = """if x!=y!=z:
+            pass"""
+        self.check(b, a)
+
+class Test_has_key(FixerTestCase):
+    fixer = "has_key"
+
+    def test_1(self):
+        b = """x = d.has_key("x") or d.has_key("y")"""
+        a = """x = "x" in d or "y" in d"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """x = a.b.c.d.has_key("x") ** 3"""
+        a = """x = ("x" in a.b.c.d) ** 3"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """x = a.b.has_key(1 + 2).__repr__()"""
+        a = """x = (1 + 2 in a.b).__repr__()"""
+        self.check(b, a)
+
+    def test_4(self):
+        b = """x = a.b.has_key(1 + 2).__repr__() ** -3 ** 4"""
+        a = """x = (1 + 2 in a.b).__repr__() ** -3 ** 4"""
+        self.check(b, a)
+
+    def test_5(self):
+        b = """x = a.has_key(f or g)"""
+        a = """x = (f or g) in a"""
+        self.check(b, a)
+
+    def test_6(self):
+        b = """x = a + b.has_key(c)"""
+        a = """x = a + (c in b)"""
+        self.check(b, a)
+
+    def test_7(self):
+        b = """x = a.has_key(lambda: 12)"""
+        a = """x = (lambda: 12) in a"""
+        self.check(b, a)
+
+    def test_8(self):
+        b = """x = a.has_key(a for a in b)"""
+        a = """x = (a for a in b) in a"""
+        self.check(b, a)
+
+    def test_9(self):
+        b = """if not a.has_key(b): pass"""
+        a = """if b not in a: pass"""
+        self.check(b, a)
+
+    def test_10(self):
+        b = """if not a.has_key(b).__repr__(): pass"""
+        a = """if not (b in a).__repr__(): pass"""
+        self.check(b, a)
+
+    def test_11(self):
+        b = """if not a.has_key(b) ** 2: pass"""
+        a = """if not (b in a) ** 2: pass"""
+        self.check(b, a)
+
+class Test_apply(FixerTestCase):
+    fixer = "apply"
+
+    def test_1(self):
+        b = """x = apply(f, g + h)"""
+        a = """x = f(*g + h)"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """y = apply(f, g, h)"""
+        a = """y = f(*g, **h)"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """z = apply(fs[0], g or h, h or g)"""
+        a = """z = fs[0](*g or h, **h or g)"""
+        self.check(b, a)
+
+    def test_4(self):
+        b = """apply(f, (x, y) + t)"""
+        a = """f(*(x, y) + t)"""
+        self.check(b, a)
+
+    def test_5(self):
+        b = """apply(f, args,)"""
+        a = """f(*args)"""
+        self.check(b, a)
+
+    def test_6(self):
+        b = """apply(f, args, kwds,)"""
+        a = """f(*args, **kwds)"""
+        self.check(b, a)
+
+    # Test that complex functions are parenthesized
+
+    def test_complex_1(self):
+        b = """x = apply(f+g, args)"""
+        a = """x = (f+g)(*args)"""
+        self.check(b, a)
+
+    def test_complex_2(self):
+        b = """x = apply(f*g, args)"""
+        a = """x = (f*g)(*args)"""
+        self.check(b, a)
+
+    def test_complex_3(self):
+        b = """x = apply(f**g, args)"""
+        a = """x = (f**g)(*args)"""
+        self.check(b, a)
+
+    # But dotted names etc. not
+
+    def test_dotted_name(self):
+        b = """x = apply(f.g, args)"""
+        a = """x = f.g(*args)"""
+        self.check(b, a)
+
+    def test_subscript(self):
+        b = """x = apply(f[x], args)"""
+        a = """x = f[x](*args)"""
+        self.check(b, a)
+
+    def test_call(self):
+        b = """x = apply(f(), args)"""
+        a = """x = f()(*args)"""
+        self.check(b, a)
+
+    # Extreme case
+    def test_extreme(self):
+        b = """x = apply(a.b.c.d.e.f, args, kwds)"""
+        a = """x = a.b.c.d.e.f(*args, **kwds)"""
+        self.check(b, a)
+
+    # XXX Comments in weird places still get lost
+    def test_weird_comments(self):
+        b = """apply(   # foo
+          f, # bar
+          args)"""
+        a = """f(*args)"""
+        self.check(b, a)
+
+    # These should *not* be touched
+
+    def test_unchanged_1(self):
+        s = """apply()"""
+        self.unchanged(s)
+
+    def test_unchanged_2(self):
+        s = """apply(f)"""
+        self.unchanged(s)
+
+    def test_unchanged_3(self):
+        s = """apply(f,)"""
+        self.unchanged(s)
+
+    def test_unchanged_4(self):
+        s = """apply(f, args, kwds, extras)"""
+        self.unchanged(s)
+
+    def test_unchanged_5(self):
+        s = """apply(f, *args, **kwds)"""
+        self.unchanged(s)
+
+    def test_unchanged_6(self):
+        s = """apply(f, *args)"""
+        self.unchanged(s)
+
+    def test_unchanged_7(self):
+        s = """apply(func=f, args=args, kwds=kwds)"""
+        self.unchanged(s)
+
+    def test_unchanged_8(self):
+        s = """apply(f, args=args, kwds=kwds)"""
+        self.unchanged(s)
+
+    def test_unchanged_9(self):
+        s = """apply(f, args, kwds=kwds)"""
+        self.unchanged(s)
+
+    def test_space_1(self):
+        a = """apply(  f,  args,   kwds)"""
+        b = """f(*args, **kwds)"""
+        self.check(a, b)
+
+    def test_space_2(self):
+        a = """apply(  f  ,args,kwds   )"""
+        b = """f(*args, **kwds)"""
+        self.check(a, b)
+
+class Test_intern(FixerTestCase):
+    fixer = "intern"
+
+    def test_prefix_preservation(self):
+        b = """x =   intern(  a  )"""
+        a = """import sys\nx =   sys.intern(  a  )"""
+        self.check(b, a)
+
+        b = """y = intern("b" # test
+              )"""
+        a = """import sys\ny = sys.intern("b" # test
+              )"""
+        self.check(b, a)
+
+        b = """z = intern(a+b+c.d,   )"""
+        a = """import sys\nz = sys.intern(a+b+c.d,   )"""
+        self.check(b, a)
+
+    def test(self):
+        b = """x = intern(a)"""
+        a = """import sys\nx = sys.intern(a)"""
+        self.check(b, a)
+
+        b = """z = intern(a+b+c.d,)"""
+        a = """import sys\nz = sys.intern(a+b+c.d,)"""
+        self.check(b, a)
+
+        b = """intern("y%s" % 5).replace("y", "")"""
+        a = """import sys\nsys.intern("y%s" % 5).replace("y", "")"""
+        self.check(b, a)
+
+    # These should not be refactored
+
+    def test_unchanged(self):
+        s = """intern(a=1)"""
+        self.unchanged(s)
+
+        s = """intern(f, g)"""
+        self.unchanged(s)
+
+        s = """intern(*h)"""
+        self.unchanged(s)
+
+        s = """intern(**i)"""
+        self.unchanged(s)
+
+        s = """intern()"""
+        self.unchanged(s)
+
+class Test_reduce(FixerTestCase):
+    fixer = "reduce"
+
+    def test_simple_call(self):
+        b = "reduce(a, b, c)"
+        a = "from functools import reduce\nreduce(a, b, c)"
+        self.check(b, a)
+
+    def test_bug_7253(self):
+        # fix_tuple_params was being bad and orphaning nodes in the tree.
+        b = "def x(arg): reduce(sum, [])"
+        a = "from functools import reduce\ndef x(arg): reduce(sum, [])"
+        self.check(b, a)
+
+    def test_call_with_lambda(self):
+        b = "reduce(lambda x, y: x + y, seq)"
+        a = "from functools import reduce\nreduce(lambda x, y: x + y, seq)"
+        self.check(b, a)
+
+    def test_unchanged(self):
+        s = "reduce(a)"
+        self.unchanged(s)
+
+        s = "reduce(a, b=42)"
+        self.unchanged(s)
+
+        s = "reduce(a, b, c, d)"
+        self.unchanged(s)
+
+        s = "reduce(**c)"
+        self.unchanged(s)
+
+        s = "reduce()"
+        self.unchanged(s)
+
+class Test_print(FixerTestCase):
+    fixer = "print"
+
+    def test_prefix_preservation(self):
+        b = """print 1,   1+1,   1+1+1"""
+        a = """print(1,   1+1,   1+1+1)"""
+        self.check(b, a)
+
+    def test_idempotency(self):
+        s = """print()"""
+        self.unchanged(s)
+
+        s = """print('')"""
+        self.unchanged(s)
+
+    def test_idempotency_print_as_function(self):
+        self.refactor.driver.grammar = pygram.python_grammar_no_print_statement
+        s = """print(1, 1+1, 1+1+1)"""
+        self.unchanged(s)
+
+        s = """print()"""
+        self.unchanged(s)
+
+        s = """print('')"""
+        self.unchanged(s)
+
+    def test_1(self):
+        b = """print 1, 1+1, 1+1+1"""
+        a = """print(1, 1+1, 1+1+1)"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """print 1, 2"""
+        a = """print(1, 2)"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """print"""
+        a = """print()"""
+        self.check(b, a)
+
+    def test_4(self):
+        # from bug 3000
+        b = """print whatever; print"""
+        a = """print(whatever); print()"""
+        self.check(b, a)
+
+    def test_5(self):
+        b = """print; print whatever;"""
+        a = """print(); print(whatever);"""
+        self.check(b, a)
+
+    def test_tuple(self):
+        b = """print (a, b, c)"""
+        a = """print((a, b, c))"""
+        self.check(b, a)
+
+    # trailing commas
+
+    def test_trailing_comma_1(self):
+        b = """print 1, 2, 3,"""
+        a = """print(1, 2, 3, end=' ')"""
+        self.check(b, a)
+
+    def test_trailing_comma_2(self):
+        b = """print 1, 2,"""
+        a = """print(1, 2, end=' ')"""
+        self.check(b, a)
+
+    def test_trailing_comma_3(self):
+        b = """print 1,"""
+        a = """print(1, end=' ')"""
+        self.check(b, a)
+
+    # >> stuff
+
+    def test_vargs_without_trailing_comma(self):
+        b = """print >>sys.stderr, 1, 2, 3"""
+        a = """print(1, 2, 3, file=sys.stderr)"""
+        self.check(b, a)
+
+    def test_with_trailing_comma(self):
+        b = """print >>sys.stderr, 1, 2,"""
+        a = """print(1, 2, end=' ', file=sys.stderr)"""
+        self.check(b, a)
+
+    def test_no_trailing_comma(self):
+        b = """print >>sys.stderr, 1+1"""
+        a = """print(1+1, file=sys.stderr)"""
+        self.check(b, a)
+
+    def test_spaces_before_file(self):
+        b = """print >>  sys.stderr"""
+        a = """print(file=sys.stderr)"""
+        self.check(b, a)
+
+    def test_with_future_print_function(self):
+        s = "from __future__ import print_function\n" \
+            "print('Hai!', end=' ')"
+        self.unchanged(s)
+
+        b = "print 'Hello, world!'"
+        a = "print('Hello, world!')"
+        self.check(b, a)
+
+
+class Test_exec(FixerTestCase):
+    fixer = "exec"
+
+    def test_prefix_preservation(self):
+        b = """  exec code in ns1,   ns2"""
+        a = """  exec(code, ns1,   ns2)"""
+        self.check(b, a)
+
+    def test_basic(self):
+        b = """exec code"""
+        a = """exec(code)"""
+        self.check(b, a)
+
+    def test_with_globals(self):
+        b = """exec code in ns"""
+        a = """exec(code, ns)"""
+        self.check(b, a)
+
+    def test_with_globals_locals(self):
+        b = """exec code in ns1, ns2"""
+        a = """exec(code, ns1, ns2)"""
+        self.check(b, a)
+
+    def test_complex_1(self):
+        b = """exec (a.b()) in ns"""
+        a = """exec((a.b()), ns)"""
+        self.check(b, a)
+
+    def test_complex_2(self):
+        b = """exec a.b() + c in ns"""
+        a = """exec(a.b() + c, ns)"""
+        self.check(b, a)
+
+    # These should not be touched
+
+    def test_unchanged_1(self):
+        s = """exec(code)"""
+        self.unchanged(s)
+
+    def test_unchanged_2(self):
+        s = """exec (code)"""
+        self.unchanged(s)
+
+    def test_unchanged_3(self):
+        s = """exec(code, ns)"""
+        self.unchanged(s)
+
+    def test_unchanged_4(self):
+        s = """exec(code, ns1, ns2)"""
+        self.unchanged(s)
+
+class Test_repr(FixerTestCase):
+    fixer = "repr"
+
+    def test_prefix_preservation(self):
+        b = """x =   `1 + 2`"""
+        a = """x =   repr(1 + 2)"""
+        self.check(b, a)
+
+    def test_simple_1(self):
+        b = """x = `1 + 2`"""
+        a = """x = repr(1 + 2)"""
+        self.check(b, a)
+
+    def test_simple_2(self):
+        b = """y = `x`"""
+        a = """y = repr(x)"""
+        self.check(b, a)
+
+    def test_complex(self):
+        b = """z = `y`.__repr__()"""
+        a = """z = repr(y).__repr__()"""
+        self.check(b, a)
+
+    def test_tuple(self):
+        b = """x = `1, 2, 3`"""
+        a = """x = repr((1, 2, 3))"""
+        self.check(b, a)
+
+    def test_nested(self):
+        b = """x = `1 + `2``"""
+        a = """x = repr(1 + repr(2))"""
+        self.check(b, a)
+
+    def test_nested_tuples(self):
+        b = """x = `1, 2 + `3, 4``"""
+        a = """x = repr((1, 2 + repr((3, 4))))"""
+        self.check(b, a)
+
+class Test_except(FixerTestCase):
+    fixer = "except"
+
+    def test_prefix_preservation(self):
+        b = """
+            try:
+                pass
+            except (RuntimeError, ImportError),    e:
+                pass"""
+        a = """
+            try:
+                pass
+            except (RuntimeError, ImportError) as    e:
+                pass"""
+        self.check(b, a)
+
+    def test_simple(self):
+        b = """
+            try:
+                pass
+            except Foo, e:
+                pass"""
+        a = """
+            try:
+                pass
+            except Foo as e:
+                pass"""
+        self.check(b, a)
+
+    def test_simple_no_space_before_target(self):
+        b = """
+            try:
+                pass
+            except Foo,e:
+                pass"""
+        a = """
+            try:
+                pass
+            except Foo as e:
+                pass"""
+        self.check(b, a)
+
+    def test_tuple_unpack(self):
+        b = """
+            def foo():
+                try:
+                    pass
+                except Exception, (f, e):
+                    pass
+                except ImportError, e:
+                    pass"""
+
+        a = """
+            def foo():
+                try:
+                    pass
+                except Exception as xxx_todo_changeme:
+                    (f, e) = xxx_todo_changeme.args
+                    pass
+                except ImportError as e:
+                    pass"""
+        self.check(b, a)
+
+    def test_multi_class(self):
+        b = """
+            try:
+                pass
+            except (RuntimeError, ImportError), e:
+                pass"""
+
+        a = """
+            try:
+                pass
+            except (RuntimeError, ImportError) as e:
+                pass"""
+        self.check(b, a)
+
+    def test_list_unpack(self):
+        b = """
+            try:
+                pass
+            except Exception, [a, b]:
+                pass"""
+
+        a = """
+            try:
+                pass
+            except Exception as xxx_todo_changeme:
+                [a, b] = xxx_todo_changeme.args
+                pass"""
+        self.check(b, a)
+
+    def test_weird_target_1(self):
+        b = """
+            try:
+                pass
+            except Exception, d[5]:
+                pass"""
+
+        a = """
+            try:
+                pass
+            except Exception as xxx_todo_changeme:
+                d[5] = xxx_todo_changeme
+                pass"""
+        self.check(b, a)
+
+    def test_weird_target_2(self):
+        b = """
+            try:
+                pass
+            except Exception, a.foo:
+                pass"""
+
+        a = """
+            try:
+                pass
+            except Exception as xxx_todo_changeme:
+                a.foo = xxx_todo_changeme
+                pass"""
+        self.check(b, a)
+
+    def test_weird_target_3(self):
+        b = """
+            try:
+                pass
+            except Exception, a().foo:
+                pass"""
+
+        a = """
+            try:
+                pass
+            except Exception as xxx_todo_changeme:
+                a().foo = xxx_todo_changeme
+                pass"""
+        self.check(b, a)
+
+    def test_bare_except(self):
+        b = """
+            try:
+                pass
+            except Exception, a:
+                pass
+            except:
+                pass"""
+
+        a = """
+            try:
+                pass
+            except Exception as a:
+                pass
+            except:
+                pass"""
+        self.check(b, a)
+
+    def test_bare_except_and_else_finally(self):
+        b = """
+            try:
+                pass
+            except Exception, a:
+                pass
+            except:
+                pass
+            else:
+                pass
+            finally:
+                pass"""
+
+        a = """
+            try:
+                pass
+            except Exception as a:
+                pass
+            except:
+                pass
+            else:
+                pass
+            finally:
+                pass"""
+        self.check(b, a)
+
+    def test_multi_fixed_excepts_before_bare_except(self):
+        b = """
+            try:
+                pass
+            except TypeError, b:
+                pass
+            except Exception, a:
+                pass
+            except:
+                pass"""
+
+        a = """
+            try:
+                pass
+            except TypeError as b:
+                pass
+            except Exception as a:
+                pass
+            except:
+                pass"""
+        self.check(b, a)
+
+    def test_one_line_suites(self):
+        b = """
+            try: raise TypeError
+            except TypeError, e:
+                pass
+            """
+        a = """
+            try: raise TypeError
+            except TypeError as e:
+                pass
+            """
+        self.check(b, a)
+        b = """
+            try:
+                raise TypeError
+            except TypeError, e: pass
+            """
+        a = """
+            try:
+                raise TypeError
+            except TypeError as e: pass
+            """
+        self.check(b, a)
+        b = """
+            try: raise TypeError
+            except TypeError, e: pass
+            """
+        a = """
+            try: raise TypeError
+            except TypeError as e: pass
+            """
+        self.check(b, a)
+        b = """
+            try: raise TypeError
+            except TypeError, e: pass
+            else: function()
+            finally: done()
+            """
+        a = """
+            try: raise TypeError
+            except TypeError as e: pass
+            else: function()
+            finally: done()
+            """
+        self.check(b, a)
+
+    # These should not be touched:
+
+    def test_unchanged_1(self):
+        s = """
+            try:
+                pass
+            except:
+                pass"""
+        self.unchanged(s)
+
+    def test_unchanged_2(self):
+        s = """
+            try:
+                pass
+            except Exception:
+                pass"""
+        self.unchanged(s)
+
+    def test_unchanged_3(self):
+        s = """
+            try:
+                pass
+            except (Exception, SystemExit):
+                pass"""
+        self.unchanged(s)
+
+class Test_raise(FixerTestCase):
+    fixer = "raise"
+
+    def test_basic(self):
+        b = """raise Exception, 5"""
+        a = """raise Exception(5)"""
+        self.check(b, a)
+
+    def test_prefix_preservation(self):
+        b = """raise Exception,5"""
+        a = """raise Exception(5)"""
+        self.check(b, a)
+
+        b = """raise   Exception,    5"""
+        a = """raise   Exception(5)"""
+        self.check(b, a)
+
+    def test_with_comments(self):
+        b = """raise Exception, 5 # foo"""
+        a = """raise Exception(5) # foo"""
+        self.check(b, a)
+
+        b = """raise E, (5, 6) % (a, b) # foo"""
+        a = """raise E((5, 6) % (a, b)) # foo"""
+        self.check(b, a)
+
+        b = """def foo():
+                    raise Exception, 5, 6 # foo"""
+        a = """def foo():
+                    raise Exception(5).with_traceback(6) # foo"""
+        self.check(b, a)
+
+    def test_None_value(self):
+        b = """raise Exception(5), None, tb"""
+        a = """raise Exception(5).with_traceback(tb)"""
+        self.check(b, a)
+
+    def test_tuple_value(self):
+        b = """raise Exception, (5, 6, 7)"""
+        a = """raise Exception(5, 6, 7)"""
+        self.check(b, a)
+
+    def test_tuple_detection(self):
+        b = """raise E, (5, 6) % (a, b)"""
+        a = """raise E((5, 6) % (a, b))"""
+        self.check(b, a)
+
+    def test_tuple_exc_1(self):
+        b = """raise (((E1, E2), E3), E4), V"""
+        a = """raise E1(V)"""
+        self.check(b, a)
+
+    def test_tuple_exc_2(self):
+        b = """raise (E1, (E2, E3), E4), V"""
+        a = """raise E1(V)"""
+        self.check(b, a)
+
+    # These should produce a warning
+
+    def test_string_exc(self):
+        s = """raise 'foo'"""
+        self.warns_unchanged(s, "Python 3 does not support string exceptions")
+
+    def test_string_exc_val(self):
+        s = """raise "foo", 5"""
+        self.warns_unchanged(s, "Python 3 does not support string exceptions")
+
+    def test_string_exc_val_tb(self):
+        s = """raise "foo", 5, 6"""
+        self.warns_unchanged(s, "Python 3 does not support string exceptions")
+
+    # These should result in traceback-assignment
+
+    def test_tb_1(self):
+        b = """def foo():
+                    raise Exception, 5, 6"""
+        a = """def foo():
+                    raise Exception(5).with_traceback(6)"""
+        self.check(b, a)
+
+    def test_tb_2(self):
+        b = """def foo():
+                    a = 5
+                    raise Exception, 5, 6
+                    b = 6"""
+        a = """def foo():
+                    a = 5
+                    raise Exception(5).with_traceback(6)
+                    b = 6"""
+        self.check(b, a)
+
+    def test_tb_3(self):
+        b = """def foo():
+                    raise Exception,5,6"""
+        a = """def foo():
+                    raise Exception(5).with_traceback(6)"""
+        self.check(b, a)
+
+    def test_tb_4(self):
+        b = """def foo():
+                    a = 5
+                    raise Exception,5,6
+                    b = 6"""
+        a = """def foo():
+                    a = 5
+                    raise Exception(5).with_traceback(6)
+                    b = 6"""
+        self.check(b, a)
+
+    def test_tb_5(self):
+        b = """def foo():
+                    raise Exception, (5, 6, 7), 6"""
+        a = """def foo():
+                    raise Exception(5, 6, 7).with_traceback(6)"""
+        self.check(b, a)
+
+    def test_tb_6(self):
+        b = """def foo():
+                    a = 5
+                    raise Exception, (5, 6, 7), 6
+                    b = 6"""
+        a = """def foo():
+                    a = 5
+                    raise Exception(5, 6, 7).with_traceback(6)
+                    b = 6"""
+        self.check(b, a)
+
+class Test_throw(FixerTestCase):
+    fixer = "throw"
+
+    def test_1(self):
+        b = """g.throw(Exception, 5)"""
+        a = """g.throw(Exception(5))"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """g.throw(Exception,5)"""
+        a = """g.throw(Exception(5))"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """g.throw(Exception, (5, 6, 7))"""
+        a = """g.throw(Exception(5, 6, 7))"""
+        self.check(b, a)
+
+    def test_4(self):
+        b = """5 + g.throw(Exception, 5)"""
+        a = """5 + g.throw(Exception(5))"""
+        self.check(b, a)
+
+    # These should produce warnings
+
+    def test_warn_1(self):
+        s = """g.throw("foo")"""
+        self.warns_unchanged(s, "Python 3 does not support string exceptions")
+
+    def test_warn_2(self):
+        s = """g.throw("foo", 5)"""
+        self.warns_unchanged(s, "Python 3 does not support string exceptions")
+
+    def test_warn_3(self):
+        s = """g.throw("foo", 5, 6)"""
+        self.warns_unchanged(s, "Python 3 does not support string exceptions")
+
+    # These should not be touched
+
+    def test_untouched_1(self):
+        s = """g.throw(Exception)"""
+        self.unchanged(s)
+
+    def test_untouched_2(self):
+        s = """g.throw(Exception(5, 6))"""
+        self.unchanged(s)
+
+    def test_untouched_3(self):
+        s = """5 + g.throw(Exception(5, 6))"""
+        self.unchanged(s)
+
+    # These should result in traceback-assignment
+
+    def test_tb_1(self):
+        b = """def foo():
+                    g.throw(Exception, 5, 6)"""
+        a = """def foo():
+                    g.throw(Exception(5).with_traceback(6))"""
+        self.check(b, a)
+
+    def test_tb_2(self):
+        b = """def foo():
+                    a = 5
+                    g.throw(Exception, 5, 6)
+                    b = 6"""
+        a = """def foo():
+                    a = 5
+                    g.throw(Exception(5).with_traceback(6))
+                    b = 6"""
+        self.check(b, a)
+
+    def test_tb_3(self):
+        b = """def foo():
+                    g.throw(Exception,5,6)"""
+        a = """def foo():
+                    g.throw(Exception(5).with_traceback(6))"""
+        self.check(b, a)
+
+    def test_tb_4(self):
+        b = """def foo():
+                    a = 5
+                    g.throw(Exception,5,6)
+                    b = 6"""
+        a = """def foo():
+                    a = 5
+                    g.throw(Exception(5).with_traceback(6))
+                    b = 6"""
+        self.check(b, a)
+
+    def test_tb_5(self):
+        b = """def foo():
+                    g.throw(Exception, (5, 6, 7), 6)"""
+        a = """def foo():
+                    g.throw(Exception(5, 6, 7).with_traceback(6))"""
+        self.check(b, a)
+
+    def test_tb_6(self):
+        b = """def foo():
+                    a = 5
+                    g.throw(Exception, (5, 6, 7), 6)
+                    b = 6"""
+        a = """def foo():
+                    a = 5
+                    g.throw(Exception(5, 6, 7).with_traceback(6))
+                    b = 6"""
+        self.check(b, a)
+
+    def test_tb_7(self):
+        b = """def foo():
+                    a + g.throw(Exception, 5, 6)"""
+        a = """def foo():
+                    a + g.throw(Exception(5).with_traceback(6))"""
+        self.check(b, a)
+
+    def test_tb_8(self):
+        b = """def foo():
+                    a = 5
+                    a + g.throw(Exception, 5, 6)
+                    b = 6"""
+        a = """def foo():
+                    a = 5
+                    a + g.throw(Exception(5).with_traceback(6))
+                    b = 6"""
+        self.check(b, a)
+
+class Test_long(FixerTestCase):
+    fixer = "long"
+
+    def test_1(self):
+        b = """x = long(x)"""
+        a = """x = int(x)"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """y = isinstance(x, long)"""
+        a = """y = isinstance(x, int)"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """z = type(x) in (int, long)"""
+        a = """z = type(x) in (int, int)"""
+        self.check(b, a)
+
+    def test_unchanged(self):
+        s = """long = True"""
+        self.unchanged(s)
+
+        s = """s.long = True"""
+        self.unchanged(s)
+
+        s = """def long(): pass"""
+        self.unchanged(s)
+
+        s = """class long(): pass"""
+        self.unchanged(s)
+
+        s = """def f(long): pass"""
+        self.unchanged(s)
+
+        s = """def f(g, long): pass"""
+        self.unchanged(s)
+
+        s = """def f(x, long=True): pass"""
+        self.unchanged(s)
+
+    def test_prefix_preservation(self):
+        b = """x =   long(  x  )"""
+        a = """x =   int(  x  )"""
+        self.check(b, a)
+
+
+class Test_execfile(FixerTestCase):
+    fixer = "execfile"
+
+    def test_conversion(self):
+        b = """execfile("fn")"""
+        a = """exec(compile(open("fn").read(), "fn", 'exec'))"""
+        self.check(b, a)
+
+        b = """execfile("fn", glob)"""
+        a = """exec(compile(open("fn").read(), "fn", 'exec'), glob)"""
+        self.check(b, a)
+
+        b = """execfile("fn", glob, loc)"""
+        a = """exec(compile(open("fn").read(), "fn", 'exec'), glob, loc)"""
+        self.check(b, a)
+
+        b = """execfile("fn", globals=glob)"""
+        a = """exec(compile(open("fn").read(), "fn", 'exec'), globals=glob)"""
+        self.check(b, a)
+
+        b = """execfile("fn", locals=loc)"""
+        a = """exec(compile(open("fn").read(), "fn", 'exec'), locals=loc)"""
+        self.check(b, a)
+
+        b = """execfile("fn", globals=glob, locals=loc)"""
+        a = """exec(compile(open("fn").read(), "fn", 'exec'), globals=glob, locals=loc)"""
+        self.check(b, a)
+
+    def test_spacing(self):
+        b = """execfile( "fn" )"""
+        a = """exec(compile(open( "fn" ).read(), "fn", 'exec'))"""
+        self.check(b, a)
+
+        b = """execfile("fn",  globals = glob)"""
+        a = """exec(compile(open("fn").read(), "fn", 'exec'),  globals = glob)"""
+        self.check(b, a)
+
+
+class Test_isinstance(FixerTestCase):
+    fixer = "isinstance"
+
+    def test_remove_multiple_items(self):
+        b = """isinstance(x, (int, int, int))"""
+        a = """isinstance(x, int)"""
+        self.check(b, a)
+
+        b = """isinstance(x, (int, float, int, int, float))"""
+        a = """isinstance(x, (int, float))"""
+        self.check(b, a)
+
+        b = """isinstance(x, (int, float, int, int, float, str))"""
+        a = """isinstance(x, (int, float, str))"""
+        self.check(b, a)
+
+        b = """isinstance(foo() + bar(), (x(), y(), x(), int, int))"""
+        a = """isinstance(foo() + bar(), (x(), y(), x(), int))"""
+        self.check(b, a)
+
+    def test_prefix_preservation(self):
+        b = """if    isinstance(  foo(), (  bar, bar, baz )) : pass"""
+        a = """if    isinstance(  foo(), (  bar, baz )) : pass"""
+        self.check(b, a)
+
+    def test_unchanged(self):
+        self.unchanged("isinstance(x, (str, int))")
+
+class Test_dict(FixerTestCase):
+    fixer = "dict"
+
+    def test_prefix_preservation(self):
+        b = "if   d. keys  (  )  : pass"
+        a = "if   list(d. keys  (  ))  : pass"
+        self.check(b, a)
+
+        b = "if   d. items  (  )  : pass"
+        a = "if   list(d. items  (  ))  : pass"
+        self.check(b, a)
+
+        b = "if   d. iterkeys  ( )  : pass"
+        a = "if   iter(d. keys  ( ))  : pass"
+        self.check(b, a)
+
+        b = "[i for i in    d.  iterkeys(  )  ]"
+        a = "[i for i in    d.  keys(  )  ]"
+        self.check(b, a)
+
+        b = "if   d. viewkeys  ( )  : pass"
+        a = "if   d. keys  ( )  : pass"
+        self.check(b, a)
+
+        b = "[i for i in    d.  viewkeys(  )  ]"
+        a = "[i for i in    d.  keys(  )  ]"
+        self.check(b, a)
+
+    def test_trailing_comment(self):
+        b = "d.keys() # foo"
+        a = "list(d.keys()) # foo"
+        self.check(b, a)
+
+        b = "d.items()  # foo"
+        a = "list(d.items())  # foo"
+        self.check(b, a)
+
+        b = "d.iterkeys()  # foo"
+        a = "iter(d.keys())  # foo"
+        self.check(b, a)
+
+        b = """[i for i in d.iterkeys() # foo
+               ]"""
+        a = """[i for i in d.keys() # foo
+               ]"""
+        self.check(b, a)
+
+        b = """[i for i in d.iterkeys() # foo
+               ]"""
+        a = """[i for i in d.keys() # foo
+               ]"""
+        self.check(b, a)
+
+        b = "d.viewitems()  # foo"
+        a = "d.items()  # foo"
+        self.check(b, a)
+
+    def test_unchanged(self):
+        for wrapper in fixer_util.consuming_calls:
+            s = "s = %s(d.keys())" % wrapper
+            self.unchanged(s)
+
+            s = "s = %s(d.values())" % wrapper
+            self.unchanged(s)
+
+            s = "s = %s(d.items())" % wrapper
+            self.unchanged(s)
+
+    def test_01(self):
+        b = "d.keys()"
+        a = "list(d.keys())"
+        self.check(b, a)
+
+        b = "a[0].foo().keys()"
+        a = "list(a[0].foo().keys())"
+        self.check(b, a)
+
+    def test_02(self):
+        b = "d.items()"
+        a = "list(d.items())"
+        self.check(b, a)
+
+    def test_03(self):
+        b = "d.values()"
+        a = "list(d.values())"
+        self.check(b, a)
+
+    def test_04(self):
+        b = "d.iterkeys()"
+        a = "iter(d.keys())"
+        self.check(b, a)
+
+    def test_05(self):
+        b = "d.iteritems()"
+        a = "iter(d.items())"
+        self.check(b, a)
+
+    def test_06(self):
+        b = "d.itervalues()"
+        a = "iter(d.values())"
+        self.check(b, a)
+
+    def test_07(self):
+        s = "list(d.keys())"
+        self.unchanged(s)
+
+    def test_08(self):
+        s = "sorted(d.keys())"
+        self.unchanged(s)
+
+    def test_09(self):
+        b = "iter(d.keys())"
+        a = "iter(list(d.keys()))"
+        self.check(b, a)
+
+    def test_10(self):
+        b = "foo(d.keys())"
+        a = "foo(list(d.keys()))"
+        self.check(b, a)
+
+    def test_11(self):
+        b = "for i in d.keys(): print i"
+        a = "for i in list(d.keys()): print i"
+        self.check(b, a)
+
+    def test_12(self):
+        b = "for i in d.iterkeys(): print i"
+        a = "for i in d.keys(): print i"
+        self.check(b, a)
+
+    def test_13(self):
+        b = "[i for i in d.keys()]"
+        a = "[i for i in list(d.keys())]"
+        self.check(b, a)
+
+    def test_14(self):
+        b = "[i for i in d.iterkeys()]"
+        a = "[i for i in d.keys()]"
+        self.check(b, a)
+
+    def test_15(self):
+        b = "(i for i in d.keys())"
+        a = "(i for i in list(d.keys()))"
+        self.check(b, a)
+
+    def test_16(self):
+        b = "(i for i in d.iterkeys())"
+        a = "(i for i in d.keys())"
+        self.check(b, a)
+
+    def test_17(self):
+        b = "iter(d.iterkeys())"
+        a = "iter(d.keys())"
+        self.check(b, a)
+
+    def test_18(self):
+        b = "list(d.iterkeys())"
+        a = "list(d.keys())"
+        self.check(b, a)
+
+    def test_19(self):
+        b = "sorted(d.iterkeys())"
+        a = "sorted(d.keys())"
+        self.check(b, a)
+
+    def test_20(self):
+        b = "foo(d.iterkeys())"
+        a = "foo(iter(d.keys()))"
+        self.check(b, a)
+
+    def test_21(self):
+        b = "print h.iterkeys().next()"
+        a = "print iter(h.keys()).next()"
+        self.check(b, a)
+
+    def test_22(self):
+        b = "print h.keys()[0]"
+        a = "print list(h.keys())[0]"
+        self.check(b, a)
+
+    def test_23(self):
+        b = "print list(h.iterkeys().next())"
+        a = "print list(iter(h.keys()).next())"
+        self.check(b, a)
+
+    def test_24(self):
+        b = "for x in h.keys()[0]: print x"
+        a = "for x in list(h.keys())[0]: print x"
+        self.check(b, a)
+
+    def test_25(self):
+        b = "d.viewkeys()"
+        a = "d.keys()"
+        self.check(b, a)
+
+    def test_26(self):
+        b = "d.viewitems()"
+        a = "d.items()"
+        self.check(b, a)
+
+    def test_27(self):
+        b = "d.viewvalues()"
+        a = "d.values()"
+        self.check(b, a)
+
+    def test_14(self):
+        b = "[i for i in d.viewkeys()]"
+        a = "[i for i in d.keys()]"
+        self.check(b, a)
+
+    def test_15(self):
+        b = "(i for i in d.viewkeys())"
+        a = "(i for i in d.keys())"
+        self.check(b, a)
+
+    def test_17(self):
+        b = "iter(d.viewkeys())"
+        a = "iter(d.keys())"
+        self.check(b, a)
+
+    def test_18(self):
+        b = "list(d.viewkeys())"
+        a = "list(d.keys())"
+        self.check(b, a)
+
+    def test_19(self):
+        b = "sorted(d.viewkeys())"
+        a = "sorted(d.keys())"
+        self.check(b, a)
+
+class Test_xrange(FixerTestCase):
+    fixer = "xrange"
+
+    def test_prefix_preservation(self):
+        b = """x =    xrange(  10  )"""
+        a = """x =    range(  10  )"""
+        self.check(b, a)
+
+        b = """x = xrange(  1  ,  10   )"""
+        a = """x = range(  1  ,  10   )"""
+        self.check(b, a)
+
+        b = """x = xrange(  0  ,  10 ,  2 )"""
+        a = """x = range(  0  ,  10 ,  2 )"""
+        self.check(b, a)
+
+    def test_single_arg(self):
+        b = """x = xrange(10)"""
+        a = """x = range(10)"""
+        self.check(b, a)
+
+    def test_two_args(self):
+        b = """x = xrange(1, 10)"""
+        a = """x = range(1, 10)"""
+        self.check(b, a)
+
+    def test_three_args(self):
+        b = """x = xrange(0, 10, 2)"""
+        a = """x = range(0, 10, 2)"""
+        self.check(b, a)
+
+    def test_wrap_in_list(self):
+        b = """x = range(10, 3, 9)"""
+        a = """x = list(range(10, 3, 9))"""
+        self.check(b, a)
+
+        b = """x = foo(range(10, 3, 9))"""
+        a = """x = foo(list(range(10, 3, 9)))"""
+        self.check(b, a)
+
+        b = """x = range(10, 3, 9) + [4]"""
+        a = """x = list(range(10, 3, 9)) + [4]"""
+        self.check(b, a)
+
+        b = """x = range(10)[::-1]"""
+        a = """x = list(range(10))[::-1]"""
+        self.check(b, a)
+
+        b = """x = range(10)  [3]"""
+        a = """x = list(range(10))  [3]"""
+        self.check(b, a)
+
+    def test_xrange_in_for(self):
+        b = """for i in xrange(10):\n    j=i"""
+        a = """for i in range(10):\n    j=i"""
+        self.check(b, a)
+
+        b = """[i for i in xrange(10)]"""
+        a = """[i for i in range(10)]"""
+        self.check(b, a)
+
+    def test_range_in_for(self):
+        self.unchanged("for i in range(10): pass")
+        self.unchanged("[i for i in range(10)]")
+
+    def test_in_contains_test(self):
+        self.unchanged("x in range(10, 3, 9)")
+
+    def test_in_consuming_context(self):
+        for call in fixer_util.consuming_calls:
+            self.unchanged("a = %s(range(10))" % call)
+
+class Test_xrange_with_reduce(FixerTestCase):
+
+    def setUp(self):
+        super(Test_xrange_with_reduce, self).setUp(["xrange", "reduce"])
+
+    def test_double_transform(self):
+        b = """reduce(x, xrange(5))"""
+        a = """from functools import reduce
+reduce(x, range(5))"""
+        self.check(b, a)
+
+class Test_raw_input(FixerTestCase):
+    fixer = "raw_input"
+
+    def test_prefix_preservation(self):
+        b = """x =    raw_input(   )"""
+        a = """x =    input(   )"""
+        self.check(b, a)
+
+        b = """x = raw_input(   ''   )"""
+        a = """x = input(   ''   )"""
+        self.check(b, a)
+
+    def test_1(self):
+        b = """x = raw_input()"""
+        a = """x = input()"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """x = raw_input('')"""
+        a = """x = input('')"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """x = raw_input('prompt')"""
+        a = """x = input('prompt')"""
+        self.check(b, a)
+
+    def test_4(self):
+        b = """x = raw_input(foo(a) + 6)"""
+        a = """x = input(foo(a) + 6)"""
+        self.check(b, a)
+
+    def test_5(self):
+        b = """x = raw_input(invite).split()"""
+        a = """x = input(invite).split()"""
+        self.check(b, a)
+
+    def test_6(self):
+        b = """x = raw_input(invite) . split ()"""
+        a = """x = input(invite) . split ()"""
+        self.check(b, a)
+
+    def test_8(self):
+        b = "x = int(raw_input())"
+        a = "x = int(input())"
+        self.check(b, a)
+
+class Test_funcattrs(FixerTestCase):
+    fixer = "funcattrs"
+
+    attrs = ["closure", "doc", "name", "defaults", "code", "globals", "dict"]
+
+    def test(self):
+        for attr in self.attrs:
+            b = "a.func_%s" % attr
+            a = "a.__%s__" % attr
+            self.check(b, a)
+
+            b = "self.foo.func_%s.foo_bar" % attr
+            a = "self.foo.__%s__.foo_bar" % attr
+            self.check(b, a)
+
+    def test_unchanged(self):
+        for attr in self.attrs:
+            s = "foo(func_%s + 5)" % attr
+            self.unchanged(s)
+
+            s = "f(foo.__%s__)" % attr
+            self.unchanged(s)
+
+            s = "f(foo.__%s__.foo)" % attr
+            self.unchanged(s)
+
+class Test_xreadlines(FixerTestCase):
+    fixer = "xreadlines"
+
+    def test_call(self):
+        b = "for x in f.xreadlines(): pass"
+        a = "for x in f: pass"
+        self.check(b, a)
+
+        b = "for x in foo().xreadlines(): pass"
+        a = "for x in foo(): pass"
+        self.check(b, a)
+
+        b = "for x in (5 + foo()).xreadlines(): pass"
+        a = "for x in (5 + foo()): pass"
+        self.check(b, a)
+
+    def test_attr_ref(self):
+        b = "foo(f.xreadlines + 5)"
+        a = "foo(f.__iter__ + 5)"
+        self.check(b, a)
+
+        b = "foo(f().xreadlines + 5)"
+        a = "foo(f().__iter__ + 5)"
+        self.check(b, a)
+
+        b = "foo((5 + f()).xreadlines + 5)"
+        a = "foo((5 + f()).__iter__ + 5)"
+        self.check(b, a)
+
+    def test_unchanged(self):
+        s = "for x in f.xreadlines(5): pass"
+        self.unchanged(s)
+
+        s = "for x in f.xreadlines(k=5): pass"
+        self.unchanged(s)
+
+        s = "for x in f.xreadlines(*k, **v): pass"
+        self.unchanged(s)
+
+        s = "foo(xreadlines)"
+        self.unchanged(s)
+
+
+class ImportsFixerTests:
+
+    def test_import_module(self):
+        for old, new in list(self.modules.items()):
+            b = "import %s" % old
+            a = "import %s" % new
+            self.check(b, a)
+
+            b = "import foo, %s, bar" % old
+            a = "import foo, %s, bar" % new
+            self.check(b, a)
+
+    def test_import_from(self):
+        for old, new in list(self.modules.items()):
+            b = "from %s import foo" % old
+            a = "from %s import foo" % new
+            self.check(b, a)
+
+            b = "from %s import foo, bar" % old
+            a = "from %s import foo, bar" % new
+            self.check(b, a)
+
+            b = "from %s import (yes, no)" % old
+            a = "from %s import (yes, no)" % new
+            self.check(b, a)
+
+    def test_import_module_as(self):
+        for old, new in list(self.modules.items()):
+            b = "import %s as foo_bar" % old
+            a = "import %s as foo_bar" % new
+            self.check(b, a)
+
+            b = "import %s as foo_bar" % old
+            a = "import %s as foo_bar" % new
+            self.check(b, a)
+
+    def test_import_from_as(self):
+        for old, new in list(self.modules.items()):
+            b = "from %s import foo as bar" % old
+            a = "from %s import foo as bar" % new
+            self.check(b, a)
+
+    def test_star(self):
+        for old, new in list(self.modules.items()):
+            b = "from %s import *" % old
+            a = "from %s import *" % new
+            self.check(b, a)
+
+    def test_import_module_usage(self):
+        for old, new in list(self.modules.items()):
+            b = """
+                import %s
+                foo(%s.bar)
+                """ % (old, old)
+            a = """
+                import %s
+                foo(%s.bar)
+                """ % (new, new)
+            self.check(b, a)
+
+            b = """
+                from %s import x
+                %s = 23
+                """ % (old, old)
+            a = """
+                from %s import x
+                %s = 23
+                """ % (new, old)
+            self.check(b, a)
+
+            s = """
+                def f():
+                    %s.method()
+                """ % (old,)
+            self.unchanged(s)
+
+            # test nested usage
+            b = """
+                import %s
+                %s.bar(%s.foo)
+                """ % (old, old, old)
+            a = """
+                import %s
+                %s.bar(%s.foo)
+                """ % (new, new, new)
+            self.check(b, a)
+
+            b = """
+                import %s
+                x.%s
+                """ % (old, old)
+            a = """
+                import %s
+                x.%s
+                """ % (new, old)
+            self.check(b, a)
+
+
+class Test_imports(FixerTestCase, ImportsFixerTests):
+    fixer = "imports"
+    from ..fixes.fix_imports import MAPPING as modules
+
+    def test_multiple_imports(self):
+        b = """import urlparse, cStringIO"""
+        a = """import urllib.parse, io"""
+        self.check(b, a)
+
+    def test_multiple_imports_as(self):
+        b = """
+            import copy_reg as bar, HTMLParser as foo, urlparse
+            s = urlparse.spam(bar.foo())
+            """
+        a = """
+            import copyreg as bar, html.parser as foo, urllib.parse
+            s = urllib.parse.spam(bar.foo())
+            """
+        self.check(b, a)
+
+
+class Test_imports2(FixerTestCase, ImportsFixerTests):
+    fixer = "imports2"
+    from ..fixes.fix_imports2 import MAPPING as modules
+
+
+class Test_imports_fixer_order(FixerTestCase, ImportsFixerTests):
+
+    def setUp(self):
+        super(Test_imports_fixer_order, self).setUp(['imports', 'imports2'])
+        from ..fixes.fix_imports2 import MAPPING as mapping2
+        self.modules = mapping2.copy()
+        from ..fixes.fix_imports import MAPPING as mapping1
+        for key in ('dbhash', 'dumbdbm', 'dbm', 'gdbm'):
+            self.modules[key] = mapping1[key]
+
+    def test_after_local_imports_refactoring(self):
+        for fix in ("imports", "imports2"):
+            self.fixer = fix
+            self.assert_runs_after("import")
+
+
+class Test_urllib(FixerTestCase):
+    fixer = "urllib"
+    from ..fixes.fix_urllib import MAPPING as modules
+
+    def test_import_module(self):
+        for old, changes in list(self.modules.items()):
+            b = "import %s" % old
+            a = "import %s" % ", ".join(map(itemgetter(0), changes))
+            self.check(b, a)
+
+    def test_import_from(self):
+        for old, changes in list(self.modules.items()):
+            all_members = []
+            for new, members in changes:
+                for member in members:
+                    all_members.append(member)
+                    b = "from %s import %s" % (old, member)
+                    a = "from %s import %s" % (new, member)
+                    self.check(b, a)
+
+                    s = "from foo import %s" % member
+                    self.unchanged(s)
+
+                b = "from %s import %s" % (old, ", ".join(members))
+                a = "from %s import %s" % (new, ", ".join(members))
+                self.check(b, a)
+
+                s = "from foo import %s" % ", ".join(members)
+                self.unchanged(s)
+
+            # test the breaking of a module into multiple replacements
+            b = "from %s import %s" % (old, ", ".join(all_members))
+            a = "\n".join(["from %s import %s" % (new, ", ".join(members))
+                            for (new, members) in changes])
+            self.check(b, a)
+
+    def test_import_module_as(self):
+        for old in self.modules:
+            s = "import %s as foo" % old
+            self.warns_unchanged(s, "This module is now multiple modules")
+
+    def test_import_from_as(self):
+        for old, changes in list(self.modules.items()):
+            for new, members in changes:
+                for member in members:
+                    b = "from %s import %s as foo_bar" % (old, member)
+                    a = "from %s import %s as foo_bar" % (new, member)
+                    self.check(b, a)
+                    b = "from %s import %s as blah, %s" % (old, member, member)
+                    a = "from %s import %s as blah, %s" % (new, member, member)
+                    self.check(b, a)
+
+    def test_star(self):
+        for old in self.modules:
+            s = "from %s import *" % old
+            self.warns_unchanged(s, "Cannot handle star imports")
+
+    def test_indented(self):
+        b = """
+def foo():
+    from urllib import urlencode, urlopen
+"""
+        a = """
+def foo():
+    from urllib.parse import urlencode
+    from urllib.request import urlopen
+"""
+        self.check(b, a)
+
+        b = """
+def foo():
+    other()
+    from urllib import urlencode, urlopen
+"""
+        a = """
+def foo():
+    other()
+    from urllib.parse import urlencode
+    from urllib.request import urlopen
+"""
+        self.check(b, a)
+
+
+
+    def test_import_module_usage(self):
+        for old, changes in list(self.modules.items()):
+            for new, members in changes:
+                for member in members:
+                    new_import = ", ".join([n for (n, mems)
+                                            in self.modules[old]])
+                    b = """
+                        import %s
+                        foo(%s.%s)
+                        """ % (old, old, member)
+                    a = """
+                        import %s
+                        foo(%s.%s)
+                        """ % (new_import, new, member)
+                    self.check(b, a)
+                    b = """
+                        import %s
+                        %s.%s(%s.%s)
+                        """ % (old, old, member, old, member)
+                    a = """
+                        import %s
+                        %s.%s(%s.%s)
+                        """ % (new_import, new, member, new, member)
+                    self.check(b, a)
+
+
+class Test_input(FixerTestCase):
+    fixer = "input"
+
+    def test_prefix_preservation(self):
+        b = """x =   input(   )"""
+        a = """x =   eval(input(   ))"""
+        self.check(b, a)
+
+        b = """x = input(   ''   )"""
+        a = """x = eval(input(   ''   ))"""
+        self.check(b, a)
+
+    def test_trailing_comment(self):
+        b = """x = input()  #  foo"""
+        a = """x = eval(input())  #  foo"""
+        self.check(b, a)
+
+    def test_idempotency(self):
+        s = """x = eval(input())"""
+        self.unchanged(s)
+
+        s = """x = eval(input(''))"""
+        self.unchanged(s)
+
+        s = """x = eval(input(foo(5) + 9))"""
+        self.unchanged(s)
+
+    def test_1(self):
+        b = """x = input()"""
+        a = """x = eval(input())"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """x = input('')"""
+        a = """x = eval(input(''))"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """x = input('prompt')"""
+        a = """x = eval(input('prompt'))"""
+        self.check(b, a)
+
+    def test_4(self):
+        b = """x = input(foo(5) + 9)"""
+        a = """x = eval(input(foo(5) + 9))"""
+        self.check(b, a)
+
+class Test_tuple_params(FixerTestCase):
+    fixer = "tuple_params"
+
+    def test_unchanged_1(self):
+        s = """def foo(): pass"""
+        self.unchanged(s)
+
+    def test_unchanged_2(self):
+        s = """def foo(a, b, c): pass"""
+        self.unchanged(s)
+
+    def test_unchanged_3(self):
+        s = """def foo(a=3, b=4, c=5): pass"""
+        self.unchanged(s)
+
+    def test_1(self):
+        b = """
+            def foo(((a, b), c)):
+                x = 5"""
+
+        a = """
+            def foo(xxx_todo_changeme):
+                ((a, b), c) = xxx_todo_changeme
+                x = 5"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """
+            def foo(((a, b), c), d):
+                x = 5"""
+
+        a = """
+            def foo(xxx_todo_changeme, d):
+                ((a, b), c) = xxx_todo_changeme
+                x = 5"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """
+            def foo(((a, b), c), d) -> e:
+                x = 5"""
+
+        a = """
+            def foo(xxx_todo_changeme, d) -> e:
+                ((a, b), c) = xxx_todo_changeme
+                x = 5"""
+        self.check(b, a)
+
+    def test_semicolon(self):
+        b = """
+            def foo(((a, b), c)): x = 5; y = 7"""
+
+        a = """
+            def foo(xxx_todo_changeme): ((a, b), c) = xxx_todo_changeme; x = 5; y = 7"""
+        self.check(b, a)
+
+    def test_keywords(self):
+        b = """
+            def foo(((a, b), c), d, e=5) -> z:
+                x = 5"""
+
+        a = """
+            def foo(xxx_todo_changeme, d, e=5) -> z:
+                ((a, b), c) = xxx_todo_changeme
+                x = 5"""
+        self.check(b, a)
+
+    def test_varargs(self):
+        b = """
+            def foo(((a, b), c), d, *vargs, **kwargs) -> z:
+                x = 5"""
+
+        a = """
+            def foo(xxx_todo_changeme, d, *vargs, **kwargs) -> z:
+                ((a, b), c) = xxx_todo_changeme
+                x = 5"""
+        self.check(b, a)
+
+    def test_multi_1(self):
+        b = """
+            def foo(((a, b), c), (d, e, f)) -> z:
+                x = 5"""
+
+        a = """
+            def foo(xxx_todo_changeme, xxx_todo_changeme1) -> z:
+                ((a, b), c) = xxx_todo_changeme
+                (d, e, f) = xxx_todo_changeme1
+                x = 5"""
+        self.check(b, a)
+
+    def test_multi_2(self):
+        b = """
+            def foo(x, ((a, b), c), d, (e, f, g), y) -> z:
+                x = 5"""
+
+        a = """
+            def foo(x, xxx_todo_changeme, d, xxx_todo_changeme1, y) -> z:
+                ((a, b), c) = xxx_todo_changeme
+                (e, f, g) = xxx_todo_changeme1
+                x = 5"""
+        self.check(b, a)
+
+    def test_docstring(self):
+        b = """
+            def foo(((a, b), c), (d, e, f)) -> z:
+                "foo foo foo foo"
+                x = 5"""
+
+        a = """
+            def foo(xxx_todo_changeme, xxx_todo_changeme1) -> z:
+                "foo foo foo foo"
+                ((a, b), c) = xxx_todo_changeme
+                (d, e, f) = xxx_todo_changeme1
+                x = 5"""
+        self.check(b, a)
+
+    def test_lambda_no_change(self):
+        s = """lambda x: x + 5"""
+        self.unchanged(s)
+
+    def test_lambda_parens_single_arg(self):
+        b = """lambda (x): x + 5"""
+        a = """lambda x: x + 5"""
+        self.check(b, a)
+
+        b = """lambda(x): x + 5"""
+        a = """lambda x: x + 5"""
+        self.check(b, a)
+
+        b = """lambda ((((x)))): x + 5"""
+        a = """lambda x: x + 5"""
+        self.check(b, a)
+
+        b = """lambda((((x)))): x + 5"""
+        a = """lambda x: x + 5"""
+        self.check(b, a)
+
+    def test_lambda_simple(self):
+        b = """lambda (x, y): x + f(y)"""
+        a = """lambda x_y: x_y[0] + f(x_y[1])"""
+        self.check(b, a)
+
+        b = """lambda(x, y): x + f(y)"""
+        a = """lambda x_y: x_y[0] + f(x_y[1])"""
+        self.check(b, a)
+
+        b = """lambda (((x, y))): x + f(y)"""
+        a = """lambda x_y: x_y[0] + f(x_y[1])"""
+        self.check(b, a)
+
+        b = """lambda(((x, y))): x + f(y)"""
+        a = """lambda x_y: x_y[0] + f(x_y[1])"""
+        self.check(b, a)
+
+    def test_lambda_one_tuple(self):
+        b = """lambda (x,): x + f(x)"""
+        a = """lambda x1: x1[0] + f(x1[0])"""
+        self.check(b, a)
+
+        b = """lambda (((x,))): x + f(x)"""
+        a = """lambda x1: x1[0] + f(x1[0])"""
+        self.check(b, a)
+
+    def test_lambda_simple_multi_use(self):
+        b = """lambda (x, y): x + x + f(x) + x"""
+        a = """lambda x_y: x_y[0] + x_y[0] + f(x_y[0]) + x_y[0]"""
+        self.check(b, a)
+
+    def test_lambda_simple_reverse(self):
+        b = """lambda (x, y): y + x"""
+        a = """lambda x_y: x_y[1] + x_y[0]"""
+        self.check(b, a)
+
+    def test_lambda_nested(self):
+        b = """lambda (x, (y, z)): x + y + z"""
+        a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]"""
+        self.check(b, a)
+
+        b = """lambda (((x, (y, z)))): x + y + z"""
+        a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + x_y_z[1][1]"""
+        self.check(b, a)
+
+    def test_lambda_nested_multi_use(self):
+        b = """lambda (x, (y, z)): x + y + f(y)"""
+        a = """lambda x_y_z: x_y_z[0] + x_y_z[1][0] + f(x_y_z[1][0])"""
+        self.check(b, a)
+
+class Test_methodattrs(FixerTestCase):
+    fixer = "methodattrs"
+
+    attrs = ["func", "self", "class"]
+
+    def test(self):
+        for attr in self.attrs:
+            b = "a.im_%s" % attr
+            if attr == "class":
+                a = "a.__self__.__class__"
+            else:
+                a = "a.__%s__" % attr
+            self.check(b, a)
+
+            b = "self.foo.im_%s.foo_bar" % attr
+            if attr == "class":
+                a = "self.foo.__self__.__class__.foo_bar"
+            else:
+                a = "self.foo.__%s__.foo_bar" % attr
+            self.check(b, a)
+
+    def test_unchanged(self):
+        for attr in self.attrs:
+            s = "foo(im_%s + 5)" % attr
+            self.unchanged(s)
+
+            s = "f(foo.__%s__)" % attr
+            self.unchanged(s)
+
+            s = "f(foo.__%s__.foo)" % attr
+            self.unchanged(s)
+
+class Test_next(FixerTestCase):
+    fixer = "next"
+
+    def test_1(self):
+        b = """it.next()"""
+        a = """next(it)"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """a.b.c.d.next()"""
+        a = """next(a.b.c.d)"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """(a + b).next()"""
+        a = """next((a + b))"""
+        self.check(b, a)
+
+    def test_4(self):
+        b = """a().next()"""
+        a = """next(a())"""
+        self.check(b, a)
+
+    def test_5(self):
+        b = """a().next() + b"""
+        a = """next(a()) + b"""
+        self.check(b, a)
+
+    def test_6(self):
+        b = """c(      a().next() + b)"""
+        a = """c(      next(a()) + b)"""
+        self.check(b, a)
+
+    def test_prefix_preservation_1(self):
+        b = """
+            for a in b:
+                foo(a)
+                a.next()
+            """
+        a = """
+            for a in b:
+                foo(a)
+                next(a)
+            """
+        self.check(b, a)
+
+    def test_prefix_preservation_2(self):
+        b = """
+            for a in b:
+                foo(a) # abc
+                # def
+                a.next()
+            """
+        a = """
+            for a in b:
+                foo(a) # abc
+                # def
+                next(a)
+            """
+        self.check(b, a)
+
+    def test_prefix_preservation_3(self):
+        b = """
+            next = 5
+            for a in b:
+                foo(a)
+                a.next()
+            """
+        a = """
+            next = 5
+            for a in b:
+                foo(a)
+                a.__next__()
+            """
+        self.check(b, a, ignore_warnings=True)
+
+    def test_prefix_preservation_4(self):
+        b = """
+            next = 5
+            for a in b:
+                foo(a) # abc
+                # def
+                a.next()
+            """
+        a = """
+            next = 5
+            for a in b:
+                foo(a) # abc
+                # def
+                a.__next__()
+            """
+        self.check(b, a, ignore_warnings=True)
+
+    def test_prefix_preservation_5(self):
+        b = """
+            next = 5
+            for a in b:
+                foo(foo(a), # abc
+                    a.next())
+            """
+        a = """
+            next = 5
+            for a in b:
+                foo(foo(a), # abc
+                    a.__next__())
+            """
+        self.check(b, a, ignore_warnings=True)
+
+    def test_prefix_preservation_6(self):
+        b = """
+            for a in b:
+                foo(foo(a), # abc
+                    a.next())
+            """
+        a = """
+            for a in b:
+                foo(foo(a), # abc
+                    next(a))
+            """
+        self.check(b, a)
+
+    def test_method_1(self):
+        b = """
+            class A:
+                def next(self):
+                    pass
+            """
+        a = """
+            class A:
+                def __next__(self):
+                    pass
+            """
+        self.check(b, a)
+
+    def test_method_2(self):
+        b = """
+            class A(object):
+                def next(self):
+                    pass
+            """
+        a = """
+            class A(object):
+                def __next__(self):
+                    pass
+            """
+        self.check(b, a)
+
+    def test_method_3(self):
+        b = """
+            class A:
+                def next(x):
+                    pass
+            """
+        a = """
+            class A:
+                def __next__(x):
+                    pass
+            """
+        self.check(b, a)
+
+    def test_method_4(self):
+        b = """
+            class A:
+                def __init__(self, foo):
+                    self.foo = foo
+
+                def next(self):
+                    pass
+
+                def __iter__(self):
+                    return self
+            """
+        a = """
+            class A:
+                def __init__(self, foo):
+                    self.foo = foo
+
+                def __next__(self):
+                    pass
+
+                def __iter__(self):
+                    return self
+            """
+        self.check(b, a)
+
+    def test_method_unchanged(self):
+        s = """
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.unchanged(s)
+
+    def test_shadowing_assign_simple(self):
+        s = """
+            next = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_assign_tuple_1(self):
+        s = """
+            (next, a) = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_assign_tuple_2(self):
+        s = """
+            (a, (b, (next, c)), a) = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_assign_list_1(self):
+        s = """
+            [next, a] = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_assign_list_2(self):
+        s = """
+            [a, [b, [next, c]], a] = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_builtin_assign(self):
+        s = """
+            def foo():
+                __builtin__.next = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_builtin_assign_in_tuple(self):
+        s = """
+            def foo():
+                (a, __builtin__.next) = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_builtin_assign_in_list(self):
+        s = """
+            def foo():
+                [a, __builtin__.next] = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_assign_to_next(self):
+        s = """
+            def foo():
+                A.next = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.unchanged(s)
+
+    def test_assign_to_next_in_tuple(self):
+        s = """
+            def foo():
+                (a, A.next) = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.unchanged(s)
+
+    def test_assign_to_next_in_list(self):
+        s = """
+            def foo():
+                [a, A.next] = foo
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.unchanged(s)
+
+    def test_shadowing_import_1(self):
+        s = """
+            import foo.bar as next
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_import_2(self):
+        s = """
+            import bar, bar.foo as next
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_import_3(self):
+        s = """
+            import bar, bar.foo as next, baz
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_import_from_1(self):
+        s = """
+            from x import next
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_import_from_2(self):
+        s = """
+            from x.a import next
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_import_from_3(self):
+        s = """
+            from x import a, next, b
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_import_from_4(self):
+        s = """
+            from x.a import a, next, b
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_funcdef_1(self):
+        s = """
+            def next(a):
+                pass
+
+            class A:
+                def next(self, a, b):
+                    pass
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_funcdef_2(self):
+        b = """
+            def next(a):
+                pass
+
+            class A:
+                def next(self):
+                    pass
+
+            it.next()
+            """
+        a = """
+            def next(a):
+                pass
+
+            class A:
+                def __next__(self):
+                    pass
+
+            it.__next__()
+            """
+        self.warns(b, a, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_global_1(self):
+        s = """
+            def f():
+                global next
+                next = 5
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_global_2(self):
+        s = """
+            def f():
+                global a, next, b
+                next = 5
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_for_simple(self):
+        s = """
+            for next in it():
+                pass
+
+            b = 5
+            c = 6
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_for_tuple_1(self):
+        s = """
+            for next, b in it():
+                pass
+
+            b = 5
+            c = 6
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_shadowing_for_tuple_2(self):
+        s = """
+            for a, (next, c), b in it():
+                pass
+
+            b = 5
+            c = 6
+            """
+        self.warns_unchanged(s, "Calls to builtin next() possibly shadowed")
+
+    def test_noncall_access_1(self):
+        b = """gnext = g.next"""
+        a = """gnext = g.__next__"""
+        self.check(b, a)
+
+    def test_noncall_access_2(self):
+        b = """f(g.next + 5)"""
+        a = """f(g.__next__ + 5)"""
+        self.check(b, a)
+
+    def test_noncall_access_3(self):
+        b = """f(g().next + 5)"""
+        a = """f(g().__next__ + 5)"""
+        self.check(b, a)
+
+class Test_nonzero(FixerTestCase):
+    fixer = "nonzero"
+
+    def test_1(self):
+        b = """
+            class A:
+                def __nonzero__(self):
+                    pass
+            """
+        a = """
+            class A:
+                def __bool__(self):
+                    pass
+            """
+        self.check(b, a)
+
+    def test_2(self):
+        b = """
+            class A(object):
+                def __nonzero__(self):
+                    pass
+            """
+        a = """
+            class A(object):
+                def __bool__(self):
+                    pass
+            """
+        self.check(b, a)
+
+    def test_unchanged_1(self):
+        s = """
+            class A(object):
+                def __bool__(self):
+                    pass
+            """
+        self.unchanged(s)
+
+    def test_unchanged_2(self):
+        s = """
+            class A(object):
+                def __nonzero__(self, a):
+                    pass
+            """
+        self.unchanged(s)
+
+    def test_unchanged_func(self):
+        s = """
+            def __nonzero__(self):
+                pass
+            """
+        self.unchanged(s)
+
+class Test_numliterals(FixerTestCase):
+    fixer = "numliterals"
+
+    def test_octal_1(self):
+        b = """0755"""
+        a = """0o755"""
+        self.check(b, a)
+
+    def test_long_int_1(self):
+        b = """a = 12L"""
+        a = """a = 12"""
+        self.check(b, a)
+
+    def test_long_int_2(self):
+        b = """a = 12l"""
+        a = """a = 12"""
+        self.check(b, a)
+
+    def test_long_hex(self):
+        b = """b = 0x12l"""
+        a = """b = 0x12"""
+        self.check(b, a)
+
+    def test_comments_and_spacing(self):
+        b = """b =   0x12L"""
+        a = """b =   0x12"""
+        self.check(b, a)
+
+        b = """b = 0755 # spam"""
+        a = """b = 0o755 # spam"""
+        self.check(b, a)
+
+    def test_unchanged_int(self):
+        s = """5"""
+        self.unchanged(s)
+
+    def test_unchanged_float(self):
+        s = """5.0"""
+        self.unchanged(s)
+
+    def test_unchanged_octal(self):
+        s = """0o755"""
+        self.unchanged(s)
+
+    def test_unchanged_hex(self):
+        s = """0xABC"""
+        self.unchanged(s)
+
+    def test_unchanged_exp(self):
+        s = """5.0e10"""
+        self.unchanged(s)
+
+    def test_unchanged_complex_int(self):
+        s = """5 + 4j"""
+        self.unchanged(s)
+
+    def test_unchanged_complex_float(self):
+        s = """5.4 + 4.9j"""
+        self.unchanged(s)
+
+    def test_unchanged_complex_bare(self):
+        s = """4j"""
+        self.unchanged(s)
+        s = """4.4j"""
+        self.unchanged(s)
+
+class Test_renames(FixerTestCase):
+    fixer = "renames"
+
+    modules = {"sys":  ("maxint", "maxsize"),
+              }
+
+    def test_import_from(self):
+        for mod, (old, new) in list(self.modules.items()):
+            b = "from %s import %s" % (mod, old)
+            a = "from %s import %s" % (mod, new)
+            self.check(b, a)
+
+            s = "from foo import %s" % old
+            self.unchanged(s)
+
+    def test_import_from_as(self):
+        for mod, (old, new) in list(self.modules.items()):
+            b = "from %s import %s as foo_bar" % (mod, old)
+            a = "from %s import %s as foo_bar" % (mod, new)
+            self.check(b, a)
+
+    def test_import_module_usage(self):
+        for mod, (old, new) in list(self.modules.items()):
+            b = """
+                import %s
+                foo(%s, %s.%s)
+                """ % (mod, mod, mod, old)
+            a = """
+                import %s
+                foo(%s, %s.%s)
+                """ % (mod, mod, mod, new)
+            self.check(b, a)
+
+    def XXX_test_from_import_usage(self):
+        # not implemented yet
+        for mod, (old, new) in list(self.modules.items()):
+            b = """
+                from %s import %s
+                foo(%s, %s)
+                """ % (mod, old, mod, old)
+            a = """
+                from %s import %s
+                foo(%s, %s)
+                """ % (mod, new, mod, new)
+            self.check(b, a)
+
+class Test_unicode(FixerTestCase):
+    fixer = "unicode"
+
+    def test_whitespace(self):
+        b = """unicode( x)"""
+        a = """str( x)"""
+        self.check(b, a)
+
+        b = """ unicode(x )"""
+        a = """ str(x )"""
+        self.check(b, a)
+
+        b = """ u'h'"""
+        a = """ 'h'"""
+        self.check(b, a)
+
+    def test_unicode_call(self):
+        b = """unicode(x, y, z)"""
+        a = """str(x, y, z)"""
+        self.check(b, a)
+
+    def test_unichr(self):
+        b = """unichr(u'h')"""
+        a = """chr('h')"""
+        self.check(b, a)
+
+    def test_unicode_literal_1(self):
+        b = '''u"x"'''
+        a = '''"x"'''
+        self.check(b, a)
+
+    def test_unicode_literal_2(self):
+        b = """ur'x'"""
+        a = """r'x'"""
+        self.check(b, a)
+
+    def test_unicode_literal_3(self):
+        b = """UR'''x''' """
+        a = """R'''x''' """
+        self.check(b, a)
+
+class Test_callable(FixerTestCase):
+    fixer = "callable"
+
+    def test_prefix_preservation(self):
+        b = """callable(    x)"""
+        a = """import collections\nisinstance(    x, collections.Callable)"""
+        self.check(b, a)
+
+        b = """if     callable(x): pass"""
+        a = """import collections
+if     isinstance(x, collections.Callable): pass"""
+        self.check(b, a)
+
+    def test_callable_call(self):
+        b = """callable(x)"""
+        a = """import collections\nisinstance(x, collections.Callable)"""
+        self.check(b, a)
+
+    def test_global_import(self):
+        b = """
+def spam(foo):
+    callable(foo)"""[1:]
+        a = """
+import collections
+def spam(foo):
+    isinstance(foo, collections.Callable)"""[1:]
+        self.check(b, a)
+
+        b = """
+import collections
+def spam(foo):
+    callable(foo)"""[1:]
+        # same output if it was already imported
+        self.check(b, a)
+
+        b = """
+from collections import *
+def spam(foo):
+    callable(foo)"""[1:]
+        a = """
+from collections import *
+import collections
+def spam(foo):
+    isinstance(foo, collections.Callable)"""[1:]
+        self.check(b, a)
+
+        b = """
+do_stuff()
+do_some_other_stuff()
+assert callable(do_stuff)"""[1:]
+        a = """
+import collections
+do_stuff()
+do_some_other_stuff()
+assert isinstance(do_stuff, collections.Callable)"""[1:]
+        self.check(b, a)
+
+        b = """
+if isinstance(do_stuff, Callable):
+    assert callable(do_stuff)
+    do_stuff(do_stuff)
+    if not callable(do_stuff):
+        exit(1)
+    else:
+        assert callable(do_stuff)
+else:
+    assert not callable(do_stuff)"""[1:]
+        a = """
+import collections
+if isinstance(do_stuff, Callable):
+    assert isinstance(do_stuff, collections.Callable)
+    do_stuff(do_stuff)
+    if not isinstance(do_stuff, collections.Callable):
+        exit(1)
+    else:
+        assert isinstance(do_stuff, collections.Callable)
+else:
+    assert not isinstance(do_stuff, collections.Callable)"""[1:]
+        self.check(b, a)
+
+    def test_callable_should_not_change(self):
+        a = """callable(*x)"""
+        self.unchanged(a)
+
+        a = """callable(x, y)"""
+        self.unchanged(a)
+
+        a = """callable(x, kw=y)"""
+        self.unchanged(a)
+
+        a = """callable()"""
+        self.unchanged(a)
+
+class Test_filter(FixerTestCase):
+    fixer = "filter"
+
+    def test_prefix_preservation(self):
+        b = """x =   filter(    foo,     'abc'   )"""
+        a = """x =   list(filter(    foo,     'abc'   ))"""
+        self.check(b, a)
+
+        b = """x =   filter(  None , 'abc'  )"""
+        a = """x =   [_f for _f in 'abc' if _f]"""
+        self.check(b, a)
+
+    def test_filter_basic(self):
+        b = """x = filter(None, 'abc')"""
+        a = """x = [_f for _f in 'abc' if _f]"""
+        self.check(b, a)
+
+        b = """x = len(filter(f, 'abc'))"""
+        a = """x = len(list(filter(f, 'abc')))"""
+        self.check(b, a)
+
+        b = """x = filter(lambda x: x%2 == 0, range(10))"""
+        a = """x = [x for x in range(10) if x%2 == 0]"""
+        self.check(b, a)
+
+        # Note the parens around x
+        b = """x = filter(lambda (x): x%2 == 0, range(10))"""
+        a = """x = [x for x in range(10) if x%2 == 0]"""
+        self.check(b, a)
+
+        # XXX This (rare) case is not supported
+##         b = """x = filter(f, 'abc')[0]"""
+##         a = """x = list(filter(f, 'abc'))[0]"""
+##         self.check(b, a)
+
+    def test_filter_nochange(self):
+        a = """b.join(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """(a + foo(5)).join(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """iter(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """list(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """list(filter(f, 'abc'))[0]"""
+        self.unchanged(a)
+        a = """set(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """set(filter(f, 'abc')).pop()"""
+        self.unchanged(a)
+        a = """tuple(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """any(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """all(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """sum(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """sorted(filter(f, 'abc'))"""
+        self.unchanged(a)
+        a = """sorted(filter(f, 'abc'), key=blah)"""
+        self.unchanged(a)
+        a = """sorted(filter(f, 'abc'), key=blah)[0]"""
+        self.unchanged(a)
+        a = """for i in filter(f, 'abc'): pass"""
+        self.unchanged(a)
+        a = """[x for x in filter(f, 'abc')]"""
+        self.unchanged(a)
+        a = """(x for x in filter(f, 'abc'))"""
+        self.unchanged(a)
+
+    def test_future_builtins(self):
+        a = "from future_builtins import spam, filter; filter(f, 'ham')"
+        self.unchanged(a)
+
+        b = """from future_builtins import spam; x = filter(f, 'abc')"""
+        a = """from future_builtins import spam; x = list(filter(f, 'abc'))"""
+        self.check(b, a)
+
+        a = "from future_builtins import *; filter(f, 'ham')"
+        self.unchanged(a)
+
+class Test_map(FixerTestCase):
+    fixer = "map"
+
+    def check(self, b, a):
+        self.unchanged("from future_builtins import map; " + b, a)
+        super(Test_map, self).check(b, a)
+
+    def test_prefix_preservation(self):
+        b = """x =    map(   f,    'abc'   )"""
+        a = """x =    list(map(   f,    'abc'   ))"""
+        self.check(b, a)
+
+    def test_trailing_comment(self):
+        b = """x = map(f, 'abc')   #   foo"""
+        a = """x = list(map(f, 'abc'))   #   foo"""
+        self.check(b, a)
+
+    def test_None_with_multiple_arguments(self):
+        s = """x = map(None, a, b, c)"""
+        self.warns_unchanged(s, "cannot convert map(None, ...) with "
+                             "multiple arguments")
+
+    def test_map_basic(self):
+        b = """x = map(f, 'abc')"""
+        a = """x = list(map(f, 'abc'))"""
+        self.check(b, a)
+
+        b = """x = len(map(f, 'abc', 'def'))"""
+        a = """x = len(list(map(f, 'abc', 'def')))"""
+        self.check(b, a)
+
+        b = """x = map(None, 'abc')"""
+        a = """x = list('abc')"""
+        self.check(b, a)
+
+        b = """x = map(lambda x: x+1, range(4))"""
+        a = """x = [x+1 for x in range(4)]"""
+        self.check(b, a)
+
+        # Note the parens around x
+        b = """x = map(lambda (x): x+1, range(4))"""
+        a = """x = [x+1 for x in range(4)]"""
+        self.check(b, a)
+
+        b = """
+            foo()
+            # foo
+            map(f, x)
+            """
+        a = """
+            foo()
+            # foo
+            list(map(f, x))
+            """
+        self.warns(b, a, "You should use a for loop here")
+
+        # XXX This (rare) case is not supported
+##         b = """x = map(f, 'abc')[0]"""
+##         a = """x = list(map(f, 'abc'))[0]"""
+##         self.check(b, a)
+
+    def test_map_nochange(self):
+        a = """b.join(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """(a + foo(5)).join(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """iter(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """list(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """list(map(f, 'abc'))[0]"""
+        self.unchanged(a)
+        a = """set(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """set(map(f, 'abc')).pop()"""
+        self.unchanged(a)
+        a = """tuple(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """any(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """all(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """sum(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """sorted(map(f, 'abc'))"""
+        self.unchanged(a)
+        a = """sorted(map(f, 'abc'), key=blah)"""
+        self.unchanged(a)
+        a = """sorted(map(f, 'abc'), key=blah)[0]"""
+        self.unchanged(a)
+        a = """for i in map(f, 'abc'): pass"""
+        self.unchanged(a)
+        a = """[x for x in map(f, 'abc')]"""
+        self.unchanged(a)
+        a = """(x for x in map(f, 'abc'))"""
+        self.unchanged(a)
+
+    def test_future_builtins(self):
+        a = "from future_builtins import spam, map, eggs; map(f, 'ham')"
+        self.unchanged(a)
+
+        b = """from future_builtins import spam, eggs; x = map(f, 'abc')"""
+        a = """from future_builtins import spam, eggs; x = list(map(f, 'abc'))"""
+        self.check(b, a)
+
+        a = "from future_builtins import *; map(f, 'ham')"
+        self.unchanged(a)
+
+class Test_zip(FixerTestCase):
+    fixer = "zip"
+
+    def check(self, b, a):
+        self.unchanged("from future_builtins import zip; " + b, a)
+        super(Test_zip, self).check(b, a)
+
+    def test_zip_basic(self):
+        b = """x = zip(a, b, c)"""
+        a = """x = list(zip(a, b, c))"""
+        self.check(b, a)
+
+        b = """x = len(zip(a, b))"""
+        a = """x = len(list(zip(a, b)))"""
+        self.check(b, a)
+
+    def test_zip_nochange(self):
+        a = """b.join(zip(a, b))"""
+        self.unchanged(a)
+        a = """(a + foo(5)).join(zip(a, b))"""
+        self.unchanged(a)
+        a = """iter(zip(a, b))"""
+        self.unchanged(a)
+        a = """list(zip(a, b))"""
+        self.unchanged(a)
+        a = """list(zip(a, b))[0]"""
+        self.unchanged(a)
+        a = """set(zip(a, b))"""
+        self.unchanged(a)
+        a = """set(zip(a, b)).pop()"""
+        self.unchanged(a)
+        a = """tuple(zip(a, b))"""
+        self.unchanged(a)
+        a = """any(zip(a, b))"""
+        self.unchanged(a)
+        a = """all(zip(a, b))"""
+        self.unchanged(a)
+        a = """sum(zip(a, b))"""
+        self.unchanged(a)
+        a = """sorted(zip(a, b))"""
+        self.unchanged(a)
+        a = """sorted(zip(a, b), key=blah)"""
+        self.unchanged(a)
+        a = """sorted(zip(a, b), key=blah)[0]"""
+        self.unchanged(a)
+        a = """for i in zip(a, b): pass"""
+        self.unchanged(a)
+        a = """[x for x in zip(a, b)]"""
+        self.unchanged(a)
+        a = """(x for x in zip(a, b))"""
+        self.unchanged(a)
+
+    def test_future_builtins(self):
+        a = "from future_builtins import spam, zip, eggs; zip(a, b)"
+        self.unchanged(a)
+
+        b = """from future_builtins import spam, eggs; x = zip(a, b)"""
+        a = """from future_builtins import spam, eggs; x = list(zip(a, b))"""
+        self.check(b, a)
+
+        a = "from future_builtins import *; zip(a, b)"
+        self.unchanged(a)
+
+class Test_standarderror(FixerTestCase):
+    fixer = "standarderror"
+
+    def test(self):
+        b = """x =    StandardError()"""
+        a = """x =    Exception()"""
+        self.check(b, a)
+
+        b = """x = StandardError(a, b, c)"""
+        a = """x = Exception(a, b, c)"""
+        self.check(b, a)
+
+        b = """f(2 + StandardError(a, b, c))"""
+        a = """f(2 + Exception(a, b, c))"""
+        self.check(b, a)
+
+class Test_types(FixerTestCase):
+    fixer = "types"
+
+    def test_basic_types_convert(self):
+        b = """types.StringType"""
+        a = """bytes"""
+        self.check(b, a)
+
+        b = """types.DictType"""
+        a = """dict"""
+        self.check(b, a)
+
+        b = """types . IntType"""
+        a = """int"""
+        self.check(b, a)
+
+        b = """types.ListType"""
+        a = """list"""
+        self.check(b, a)
+
+        b = """types.LongType"""
+        a = """int"""
+        self.check(b, a)
+
+        b = """types.NoneType"""
+        a = """type(None)"""
+        self.check(b, a)
+
+class Test_idioms(FixerTestCase):
+    fixer = "idioms"
+
+    def test_while(self):
+        b = """while 1: foo()"""
+        a = """while True: foo()"""
+        self.check(b, a)
+
+        b = """while   1: foo()"""
+        a = """while   True: foo()"""
+        self.check(b, a)
+
+        b = """
+            while 1:
+                foo()
+            """
+        a = """
+            while True:
+                foo()
+            """
+        self.check(b, a)
+
+    def test_while_unchanged(self):
+        s = """while 11: foo()"""
+        self.unchanged(s)
+
+        s = """while 0: foo()"""
+        self.unchanged(s)
+
+        s = """while foo(): foo()"""
+        self.unchanged(s)
+
+        s = """while []: foo()"""
+        self.unchanged(s)
+
+    def test_eq_simple(self):
+        b = """type(x) == T"""
+        a = """isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   type(x) == T: pass"""
+        a = """if   isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_eq_reverse(self):
+        b = """T == type(x)"""
+        a = """isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   T == type(x): pass"""
+        a = """if   isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_eq_expression(self):
+        b = """type(x+y) == d.get('T')"""
+        a = """isinstance(x+y, d.get('T'))"""
+        self.check(b, a)
+
+        b = """type(   x  +  y) == d.get('T')"""
+        a = """isinstance(x  +  y, d.get('T'))"""
+        self.check(b, a)
+
+    def test_is_simple(self):
+        b = """type(x) is T"""
+        a = """isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   type(x) is T: pass"""
+        a = """if   isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_is_reverse(self):
+        b = """T is type(x)"""
+        a = """isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   T is type(x): pass"""
+        a = """if   isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_is_expression(self):
+        b = """type(x+y) is d.get('T')"""
+        a = """isinstance(x+y, d.get('T'))"""
+        self.check(b, a)
+
+        b = """type(   x  +  y) is d.get('T')"""
+        a = """isinstance(x  +  y, d.get('T'))"""
+        self.check(b, a)
+
+    def test_is_not_simple(self):
+        b = """type(x) is not T"""
+        a = """not isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   type(x) is not T: pass"""
+        a = """if   not isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_is_not_reverse(self):
+        b = """T is not type(x)"""
+        a = """not isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   T is not type(x): pass"""
+        a = """if   not isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_is_not_expression(self):
+        b = """type(x+y) is not d.get('T')"""
+        a = """not isinstance(x+y, d.get('T'))"""
+        self.check(b, a)
+
+        b = """type(   x  +  y) is not d.get('T')"""
+        a = """not isinstance(x  +  y, d.get('T'))"""
+        self.check(b, a)
+
+    def test_ne_simple(self):
+        b = """type(x) != T"""
+        a = """not isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   type(x) != T: pass"""
+        a = """if   not isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_ne_reverse(self):
+        b = """T != type(x)"""
+        a = """not isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   T != type(x): pass"""
+        a = """if   not isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_ne_expression(self):
+        b = """type(x+y) != d.get('T')"""
+        a = """not isinstance(x+y, d.get('T'))"""
+        self.check(b, a)
+
+        b = """type(   x  +  y) != d.get('T')"""
+        a = """not isinstance(x  +  y, d.get('T'))"""
+        self.check(b, a)
+
+    def test_type_unchanged(self):
+        a = """type(x).__name__"""
+        self.unchanged(a)
+
+    def test_sort_list_call(self):
+        b = """
+            v = list(t)
+            v.sort()
+            foo(v)
+            """
+        a = """
+            v = sorted(t)
+            foo(v)
+            """
+        self.check(b, a)
+
+        b = """
+            v = list(foo(b) + d)
+            v.sort()
+            foo(v)
+            """
+        a = """
+            v = sorted(foo(b) + d)
+            foo(v)
+            """
+        self.check(b, a)
+
+        b = """
+            while x:
+                v = list(t)
+                v.sort()
+                foo(v)
+            """
+        a = """
+            while x:
+                v = sorted(t)
+                foo(v)
+            """
+        self.check(b, a)
+
+        b = """
+            v = list(t)
+            # foo
+            v.sort()
+            foo(v)
+            """
+        a = """
+            v = sorted(t)
+            # foo
+            foo(v)
+            """
+        self.check(b, a)
+
+        b = r"""
+            v = list(   t)
+            v.sort()
+            foo(v)
+            """
+        a = r"""
+            v = sorted(   t)
+            foo(v)
+            """
+        self.check(b, a)
+
+        b = r"""
+            try:
+                m = list(s)
+                m.sort()
+            except: pass
+            """
+
+        a = r"""
+            try:
+                m = sorted(s)
+            except: pass
+            """
+        self.check(b, a)
+
+        b = r"""
+            try:
+                m = list(s)
+                # foo
+                m.sort()
+            except: pass
+            """
+
+        a = r"""
+            try:
+                m = sorted(s)
+                # foo
+            except: pass
+            """
+        self.check(b, a)
+
+        b = r"""
+            m = list(s)
+            # more comments
+            m.sort()"""
+
+        a = r"""
+            m = sorted(s)
+            # more comments"""
+        self.check(b, a)
+
+    def test_sort_simple_expr(self):
+        b = """
+            v = t
+            v.sort()
+            foo(v)
+            """
+        a = """
+            v = sorted(t)
+            foo(v)
+            """
+        self.check(b, a)
+
+        b = """
+            v = foo(b)
+            v.sort()
+            foo(v)
+            """
+        a = """
+            v = sorted(foo(b))
+            foo(v)
+            """
+        self.check(b, a)
+
+        b = """
+            v = b.keys()
+            v.sort()
+            foo(v)
+            """
+        a = """
+            v = sorted(b.keys())
+            foo(v)
+            """
+        self.check(b, a)
+
+        b = """
+            v = foo(b) + d
+            v.sort()
+            foo(v)
+            """
+        a = """
+            v = sorted(foo(b) + d)
+            foo(v)
+            """
+        self.check(b, a)
+
+        b = """
+            while x:
+                v = t
+                v.sort()
+                foo(v)
+            """
+        a = """
+            while x:
+                v = sorted(t)
+                foo(v)
+            """
+        self.check(b, a)
+
+        b = """
+            v = t
+            # foo
+            v.sort()
+            foo(v)
+            """
+        a = """
+            v = sorted(t)
+            # foo
+            foo(v)
+            """
+        self.check(b, a)
+
+        b = r"""
+            v =   t
+            v.sort()
+            foo(v)
+            """
+        a = r"""
+            v =   sorted(t)
+            foo(v)
+            """
+        self.check(b, a)
+
+    def test_sort_unchanged(self):
+        s = """
+            v = list(t)
+            w.sort()
+            foo(w)
+            """
+        self.unchanged(s)
+
+        s = """
+            v = list(t)
+            v.sort(u)
+            foo(v)
+            """
+        self.unchanged(s)
+
+class Test_basestring(FixerTestCase):
+    fixer = "basestring"
+
+    def test_basestring(self):
+        b = """isinstance(x, basestring)"""
+        a = """isinstance(x, str)"""
+        self.check(b, a)
+
+class Test_buffer(FixerTestCase):
+    fixer = "buffer"
+
+    def test_buffer(self):
+        b = """x = buffer(y)"""
+        a = """x = memoryview(y)"""
+        self.check(b, a)
+
+    def test_slicing(self):
+        b = """buffer(y)[4:5]"""
+        a = """memoryview(y)[4:5]"""
+        self.check(b, a)
+
+class Test_future(FixerTestCase):
+    fixer = "future"
+
+    def test_future(self):
+        b = """from __future__ import braces"""
+        a = """"""
+        self.check(b, a)
+
+        b = """# comment\nfrom __future__ import braces"""
+        a = """# comment\n"""
+        self.check(b, a)
+
+        b = """from __future__ import braces\n# comment"""
+        a = """\n# comment"""
+        self.check(b, a)
+
+    def test_run_order(self):
+        self.assert_runs_after('print')
+
+class Test_itertools(FixerTestCase):
+    fixer = "itertools"
+
+    def checkall(self, before, after):
+        # Because we need to check with and without the itertools prefix
+        # and on each of the three functions, these loops make it all
+        # much easier
+        for i in ('itertools.', ''):
+            for f in ('map', 'filter', 'zip'):
+                b = before %(i+'i'+f)
+                a = after %(f)
+                self.check(b, a)
+
+    def test_0(self):
+        # A simple example -- test_1 covers exactly the same thing,
+        # but it's not quite as clear.
+        b = "itertools.izip(a, b)"
+        a = "zip(a, b)"
+        self.check(b, a)
+
+    def test_1(self):
+        b = """%s(f, a)"""
+        a = """%s(f, a)"""
+        self.checkall(b, a)
+
+    def test_2(self):
+        b = """itertools.ifilterfalse(a, b)"""
+        a = """itertools.filterfalse(a, b)"""
+        self.check(b, a)
+
+    def test_4(self):
+        b = """ifilterfalse(a, b)"""
+        a = """filterfalse(a, b)"""
+        self.check(b, a)
+
+    def test_space_1(self):
+        b = """    %s(f, a)"""
+        a = """    %s(f, a)"""
+        self.checkall(b, a)
+
+    def test_space_2(self):
+        b = """    itertools.ifilterfalse(a, b)"""
+        a = """    itertools.filterfalse(a, b)"""
+        self.check(b, a)
+
+    def test_run_order(self):
+        self.assert_runs_after('map', 'zip', 'filter')
+
+class Test_itertools_imports(FixerTestCase):
+    fixer = 'itertools_imports'
+
+    def test_reduced(self):
+        b = "from itertools import imap, izip, foo"
+        a = "from itertools import foo"
+        self.check(b, a)
+
+        b = "from itertools import bar, imap, izip, foo"
+        a = "from itertools import bar, foo"
+        self.check(b, a)
+
+        b = "from itertools import chain, imap, izip"
+        a = "from itertools import chain"
+        self.check(b, a)
+
+    def test_comments(self):
+        b = "#foo\nfrom itertools import imap, izip"
+        a = "#foo\n"
+        self.check(b, a)
+
+    def test_none(self):
+        b = "from itertools import imap, izip"
+        a = ""
+        self.check(b, a)
+
+        b = "from itertools import izip"
+        a = ""
+        self.check(b, a)
+
+    def test_import_as(self):
+        b = "from itertools import izip, bar as bang, imap"
+        a = "from itertools import bar as bang"
+        self.check(b, a)
+
+        b = "from itertools import izip as _zip, imap, bar"
+        a = "from itertools import bar"
+        self.check(b, a)
+
+        b = "from itertools import imap as _map"
+        a = ""
+        self.check(b, a)
+
+        b = "from itertools import imap as _map, izip as _zip"
+        a = ""
+        self.check(b, a)
+
+        s = "from itertools import bar as bang"
+        self.unchanged(s)
+
+    def test_ifilter(self):
+        b = "from itertools import ifilterfalse"
+        a = "from itertools import filterfalse"
+        self.check(b, a)
+
+        b = "from itertools import imap, ifilterfalse, foo"
+        a = "from itertools import filterfalse, foo"
+        self.check(b, a)
+
+        b = "from itertools import bar, ifilterfalse, foo"
+        a = "from itertools import bar, filterfalse, foo"
+        self.check(b, a)
+
+    def test_import_star(self):
+        s = "from itertools import *"
+        self.unchanged(s)
+
+
+    def test_unchanged(self):
+        s = "from itertools import foo"
+        self.unchanged(s)
+
+
+class Test_import(FixerTestCase):
+    fixer = "import"
+
+    def setUp(self):
+        super(Test_import, self).setUp()
+        # Need to replace fix_import's exists method
+        # so we can check that it's doing the right thing
+        self.files_checked = []
+        self.present_files = set()
+        self.always_exists = True
+        def fake_exists(name):
+            self.files_checked.append(name)
+            return self.always_exists or (name in self.present_files)
+
+        from lib2to3.fixes import fix_import
+        fix_import.exists = fake_exists
+
+    def tearDown(self):
+        from lib2to3.fixes import fix_import
+        fix_import.exists = os.path.exists
+
+    def check_both(self, b, a):
+        self.always_exists = True
+        super(Test_import, self).check(b, a)
+        self.always_exists = False
+        super(Test_import, self).unchanged(b)
+
+    def test_files_checked(self):
+        def p(path):
+            # Takes a unix path and returns a path with correct separators
+            return os.path.pathsep.join(path.split("/"))
+
+        self.always_exists = False
+        self.present_files = set(['__init__.py'])
+        expected_extensions = ('.py', os.path.sep, '.pyc', '.so', '.sl', '.pyd')
+        names_to_test = (p("/spam/eggs.py"), "ni.py", p("../../shrubbery.py"))
+
+        for name in names_to_test:
+            self.files_checked = []
+            self.filename = name
+            self.unchanged("import jam")
+
+            if os.path.dirname(name):
+                name = os.path.dirname(name) + '/jam'
+            else:
+                name = 'jam'
+            expected_checks = set(name + ext for ext in expected_extensions)
+            expected_checks.add("__init__.py")
+
+            self.assertEqual(set(self.files_checked), expected_checks)
+
+    def test_not_in_package(self):
+        s = "import bar"
+        self.always_exists = False
+        self.present_files = set(["bar.py"])
+        self.unchanged(s)
+
+    def test_with_absolute_import_enabled(self):
+        s = "from __future__ import absolute_import\nimport bar"
+        self.always_exists = False
+        self.present_files = set(["__init__.py", "bar.py"])
+        self.unchanged(s)
+
+    def test_in_package(self):
+        b = "import bar"
+        a = "from . import bar"
+        self.always_exists = False
+        self.present_files = set(["__init__.py", "bar.py"])
+        self.check(b, a)
+
+    def test_import_from_package(self):
+        b = "import bar"
+        a = "from . import bar"
+        self.always_exists = False
+        self.present_files = set(["__init__.py", "bar" + os.path.sep])
+        self.check(b, a)
+
+    def test_already_relative_import(self):
+        s = "from . import bar"
+        self.unchanged(s)
+
+    def test_comments_and_indent(self):
+        b = "import bar # Foo"
+        a = "from . import bar # Foo"
+        self.check(b, a)
+
+    def test_from(self):
+        b = "from foo import bar, baz"
+        a = "from .foo import bar, baz"
+        self.check_both(b, a)
+
+        b = "from foo import bar"
+        a = "from .foo import bar"
+        self.check_both(b, a)
+
+        b = "from foo import (bar, baz)"
+        a = "from .foo import (bar, baz)"
+        self.check_both(b, a)
+
+    def test_dotted_from(self):
+        b = "from green.eggs import ham"
+        a = "from .green.eggs import ham"
+        self.check_both(b, a)
+
+    def test_from_as(self):
+        b = "from green.eggs import ham as spam"
+        a = "from .green.eggs import ham as spam"
+        self.check_both(b, a)
+
+    def test_import(self):
+        b = "import foo"
+        a = "from . import foo"
+        self.check_both(b, a)
+
+        b = "import foo, bar"
+        a = "from . import foo, bar"
+        self.check_both(b, a)
+
+        b = "import foo, bar, x"
+        a = "from . import foo, bar, x"
+        self.check_both(b, a)
+
+        b = "import x, y, z"
+        a = "from . import x, y, z"
+        self.check_both(b, a)
+
+    def test_import_as(self):
+        b = "import foo as x"
+        a = "from . import foo as x"
+        self.check_both(b, a)
+
+        b = "import a as b, b as c, c as d"
+        a = "from . import a as b, b as c, c as d"
+        self.check_both(b, a)
+
+    def test_local_and_absolute(self):
+        self.always_exists = False
+        self.present_files = set(["foo.py", "__init__.py"])
+
+        s = "import foo, bar"
+        self.warns_unchanged(s, "absolute and local imports together")
+
+    def test_dotted_import(self):
+        b = "import foo.bar"
+        a = "from . import foo.bar"
+        self.check_both(b, a)
+
+    def test_dotted_import_as(self):
+        b = "import foo.bar as bang"
+        a = "from . import foo.bar as bang"
+        self.check_both(b, a)
+
+    def test_prefix(self):
+        b = """
+        # prefix
+        import foo.bar
+        """
+        a = """
+        # prefix
+        from . import foo.bar
+        """
+        self.check_both(b, a)
+
+
+class Test_set_literal(FixerTestCase):
+
+    fixer = "set_literal"
+
+    def test_basic(self):
+        b = """set([1, 2, 3])"""
+        a = """{1, 2, 3}"""
+        self.check(b, a)
+
+        b = """set((1, 2, 3))"""
+        a = """{1, 2, 3}"""
+        self.check(b, a)
+
+        b = """set((1,))"""
+        a = """{1}"""
+        self.check(b, a)
+
+        b = """set([1])"""
+        self.check(b, a)
+
+        b = """set((a, b))"""
+        a = """{a, b}"""
+        self.check(b, a)
+
+        b = """set([a, b])"""
+        self.check(b, a)
+
+        b = """set((a*234, f(args=23)))"""
+        a = """{a*234, f(args=23)}"""
+        self.check(b, a)
+
+        b = """set([a*23, f(23)])"""
+        a = """{a*23, f(23)}"""
+        self.check(b, a)
+
+        b = """set([a-234**23])"""
+        a = """{a-234**23}"""
+        self.check(b, a)
+
+    def test_listcomps(self):
+        b = """set([x for x in y])"""
+        a = """{x for x in y}"""
+        self.check(b, a)
+
+        b = """set([x for x in y if x == m])"""
+        a = """{x for x in y if x == m}"""
+        self.check(b, a)
+
+        b = """set([x for x in y for a in b])"""
+        a = """{x for x in y for a in b}"""
+        self.check(b, a)
+
+        b = """set([f(x) - 23 for x in y])"""
+        a = """{f(x) - 23 for x in y}"""
+        self.check(b, a)
+
+    def test_whitespace(self):
+        b = """set( [1, 2])"""
+        a = """{1, 2}"""
+        self.check(b, a)
+
+        b = """set([1 ,  2])"""
+        a = """{1 ,  2}"""
+        self.check(b, a)
+
+        b = """set([ 1 ])"""
+        a = """{ 1 }"""
+        self.check(b, a)
+
+        b = """set( [1] )"""
+        a = """{1}"""
+        self.check(b, a)
+
+        b = """set([  1,  2  ])"""
+        a = """{  1,  2  }"""
+        self.check(b, a)
+
+        b = """set([x  for x in y ])"""
+        a = """{x  for x in y }"""
+        self.check(b, a)
+
+        b = """set(
+                   [1, 2]
+               )
+            """
+        a = """{1, 2}\n"""
+        self.check(b, a)
+
+    def test_comments(self):
+        b = """set((1, 2)) # Hi"""
+        a = """{1, 2} # Hi"""
+        self.check(b, a)
+
+        # This isn't optimal behavior, but the fixer is optional.
+        b = """
+            # Foo
+            set( # Bar
+               (1, 2)
+            )
+            """
+        a = """
+            # Foo
+            {1, 2}
+            """
+        self.check(b, a)
+
+    def test_unchanged(self):
+        s = """set()"""
+        self.unchanged(s)
+
+        s = """set(a)"""
+        self.unchanged(s)
+
+        s = """set(a, b, c)"""
+        self.unchanged(s)
+
+        # Don't transform generators because they might have to be lazy.
+        s = """set(x for x in y)"""
+        self.unchanged(s)
+
+        s = """set(x for x in y if z)"""
+        self.unchanged(s)
+
+        s = """set(a*823-23**2 + f(23))"""
+        self.unchanged(s)
+
+
+class Test_sys_exc(FixerTestCase):
+    fixer = "sys_exc"
+
+    def test_0(self):
+        b = "sys.exc_type"
+        a = "sys.exc_info()[0]"
+        self.check(b, a)
+
+    def test_1(self):
+        b = "sys.exc_value"
+        a = "sys.exc_info()[1]"
+        self.check(b, a)
+
+    def test_2(self):
+        b = "sys.exc_traceback"
+        a = "sys.exc_info()[2]"
+        self.check(b, a)
+
+    def test_3(self):
+        b = "sys.exc_type # Foo"
+        a = "sys.exc_info()[0] # Foo"
+        self.check(b, a)
+
+    def test_4(self):
+        b = "sys.  exc_type"
+        a = "sys.  exc_info()[0]"
+        self.check(b, a)
+
+    def test_5(self):
+        b = "sys  .exc_type"
+        a = "sys  .exc_info()[0]"
+        self.check(b, a)
+
+
+class Test_paren(FixerTestCase):
+    fixer = "paren"
+
+    def test_0(self):
+        b = """[i for i in 1, 2 ]"""
+        a = """[i for i in (1, 2) ]"""
+        self.check(b, a)
+
+    def test_1(self):
+        b = """[i for i in 1, 2, ]"""
+        a = """[i for i in (1, 2,) ]"""
+        self.check(b, a)
+
+    def test_2(self):
+        b = """[i for i  in     1, 2 ]"""
+        a = """[i for i  in     (1, 2) ]"""
+        self.check(b, a)
+
+    def test_3(self):
+        b = """[i for i in 1, 2 if i]"""
+        a = """[i for i in (1, 2) if i]"""
+        self.check(b, a)
+
+    def test_4(self):
+        b = """[i for i in 1,    2    ]"""
+        a = """[i for i in (1,    2)    ]"""
+        self.check(b, a)
+
+    def test_5(self):
+        b = """(i for i in 1, 2)"""
+        a = """(i for i in (1, 2))"""
+        self.check(b, a)
+
+    def test_6(self):
+        b = """(i for i in 1   ,2   if i)"""
+        a = """(i for i in (1   ,2)   if i)"""
+        self.check(b, a)
+
+    def test_unchanged_0(self):
+        s = """[i for i in (1, 2)]"""
+        self.unchanged(s)
+
+    def test_unchanged_1(self):
+        s = """[i for i in foo()]"""
+        self.unchanged(s)
+
+    def test_unchanged_2(self):
+        s = """[i for i in (1, 2) if nothing]"""
+        self.unchanged(s)
+
+    def test_unchanged_3(self):
+        s = """(i for i in (1, 2))"""
+        self.unchanged(s)
+
+    def test_unchanged_4(self):
+        s = """[i for i in m]"""
+        self.unchanged(s)
+
+class Test_metaclass(FixerTestCase):
+
+    fixer = 'metaclass'
+
+    def test_unchanged(self):
+        self.unchanged("class X(): pass")
+        self.unchanged("class X(object): pass")
+        self.unchanged("class X(object1, object2): pass")
+        self.unchanged("class X(object1, object2, object3): pass")
+        self.unchanged("class X(metaclass=Meta): pass")
+        self.unchanged("class X(b, arg=23, metclass=Meta): pass")
+        self.unchanged("class X(b, arg=23, metaclass=Meta, other=42): pass")
+
+        s = """
+        class X:
+            def __metaclass__(self): pass
+        """
+        self.unchanged(s)
+
+        s = """
+        class X:
+            a[23] = 74
+        """
+        self.unchanged(s)
+
+    def test_comments(self):
+        b = """
+        class X:
+            # hi
+            __metaclass__ = AppleMeta
+        """
+        a = """
+        class X(metaclass=AppleMeta):
+            # hi
+            pass
+        """
+        self.check(b, a)
+
+        b = """
+        class X:
+            __metaclass__ = Meta
+            # Bedtime!
+        """
+        a = """
+        class X(metaclass=Meta):
+            pass
+            # Bedtime!
+        """
+        self.check(b, a)
+
+    def test_meta(self):
+        # no-parent class, odd body
+        b = """
+        class X():
+            __metaclass__ = Q
+            pass
+        """
+        a = """
+        class X(metaclass=Q):
+            pass
+        """
+        self.check(b, a)
+
+        # one parent class, no body
+        b = """class X(object): __metaclass__ = Q"""
+        a = """class X(object, metaclass=Q): pass"""
+        self.check(b, a)
+
+
+        # one parent, simple body
+        b = """
+        class X(object):
+            __metaclass__ = Meta
+            bar = 7
+        """
+        a = """
+        class X(object, metaclass=Meta):
+            bar = 7
+        """
+        self.check(b, a)
+
+        b = """
+        class X:
+            __metaclass__ = Meta; x = 4; g = 23
+        """
+        a = """
+        class X(metaclass=Meta):
+            x = 4; g = 23
+        """
+        self.check(b, a)
+
+        # one parent, simple body, __metaclass__ last
+        b = """
+        class X(object):
+            bar = 7
+            __metaclass__ = Meta
+        """
+        a = """
+        class X(object, metaclass=Meta):
+            bar = 7
+        """
+        self.check(b, a)
+
+        # redefining __metaclass__
+        b = """
+        class X():
+            __metaclass__ = A
+            __metaclass__ = B
+            bar = 7
+        """
+        a = """
+        class X(metaclass=B):
+            bar = 7
+        """
+        self.check(b, a)
+
+        # multiple inheritance, simple body
+        b = """
+        class X(clsA, clsB):
+            __metaclass__ = Meta
+            bar = 7
+        """
+        a = """
+        class X(clsA, clsB, metaclass=Meta):
+            bar = 7
+        """
+        self.check(b, a)
+
+        # keywords in the class statement
+        b = """class m(a, arg=23): __metaclass__ = Meta"""
+        a = """class m(a, arg=23, metaclass=Meta): pass"""
+        self.check(b, a)
+
+        b = """
+        class X(expression(2 + 4)):
+            __metaclass__ = Meta
+        """
+        a = """
+        class X(expression(2 + 4), metaclass=Meta):
+            pass
+        """
+        self.check(b, a)
+
+        b = """
+        class X(expression(2 + 4), x**4):
+            __metaclass__ = Meta
+        """
+        a = """
+        class X(expression(2 + 4), x**4, metaclass=Meta):
+            pass
+        """
+        self.check(b, a)
+
+        b = """
+        class X:
+            __metaclass__ = Meta
+            save.py = 23
+        """
+        a = """
+        class X(metaclass=Meta):
+            save.py = 23
+        """
+        self.check(b, a)
+
+
+class Test_getcwdu(FixerTestCase):
+
+    fixer = 'getcwdu'
+
+    def test_basic(self):
+        b = """os.getcwdu"""
+        a = """os.getcwd"""
+        self.check(b, a)
+
+        b = """os.getcwdu()"""
+        a = """os.getcwd()"""
+        self.check(b, a)
+
+        b = """meth = os.getcwdu"""
+        a = """meth = os.getcwd"""
+        self.check(b, a)
+
+        b = """os.getcwdu(args)"""
+        a = """os.getcwd(args)"""
+        self.check(b, a)
+
+    def test_comment(self):
+        b = """os.getcwdu() # Foo"""
+        a = """os.getcwd() # Foo"""
+        self.check(b, a)
+
+    def test_unchanged(self):
+        s = """os.getcwd()"""
+        self.unchanged(s)
+
+        s = """getcwdu()"""
+        self.unchanged(s)
+
+        s = """os.getcwdb()"""
+        self.unchanged(s)
+
+    def test_indentation(self):
+        b = """
+            if 1:
+                os.getcwdu()
+            """
+        a = """
+            if 1:
+                os.getcwd()
+            """
+        self.check(b, a)
+
+    def test_multilation(self):
+        b = """os .getcwdu()"""
+        a = """os .getcwd()"""
+        self.check(b, a)
+
+        b = """os.  getcwdu"""
+        a = """os.  getcwd"""
+        self.check(b, a)
+
+        b = """os.getcwdu (  )"""
+        a = """os.getcwd (  )"""
+        self.check(b, a)
+
+
+class Test_operator(FixerTestCase):
+
+    fixer = "operator"
+
+    def test_operator_isCallable(self):
+        b = "operator.isCallable(x)"
+        a = "hasattr(x, '__call__')"
+        self.check(b, a)
+
+    def test_operator_sequenceIncludes(self):
+        b = "operator.sequenceIncludes(x, y)"
+        a = "operator.contains(x, y)"
+        self.check(b, a)
+
+        b = "operator .sequenceIncludes(x, y)"
+        a = "operator .contains(x, y)"
+        self.check(b, a)
+
+        b = "operator.  sequenceIncludes(x, y)"
+        a = "operator.  contains(x, y)"
+        self.check(b, a)
+
+    def test_operator_isSequenceType(self):
+        b = "operator.isSequenceType(x)"
+        a = "import collections\nisinstance(x, collections.Sequence)"
+        self.check(b, a)
+
+    def test_operator_isMappingType(self):
+        b = "operator.isMappingType(x)"
+        a = "import collections\nisinstance(x, collections.Mapping)"
+        self.check(b, a)
+
+    def test_operator_isNumberType(self):
+        b = "operator.isNumberType(x)"
+        a = "import numbers\nisinstance(x, numbers.Number)"
+        self.check(b, a)
+
+    def test_operator_repeat(self):
+        b = "operator.repeat(x, n)"
+        a = "operator.mul(x, n)"
+        self.check(b, a)
+
+        b = "operator .repeat(x, n)"
+        a = "operator .mul(x, n)"
+        self.check(b, a)
+
+        b = "operator.  repeat(x, n)"
+        a = "operator.  mul(x, n)"
+        self.check(b, a)
+
+    def test_operator_irepeat(self):
+        b = "operator.irepeat(x, n)"
+        a = "operator.imul(x, n)"
+        self.check(b, a)
+
+        b = "operator .irepeat(x, n)"
+        a = "operator .imul(x, n)"
+        self.check(b, a)
+
+        b = "operator.  irepeat(x, n)"
+        a = "operator.  imul(x, n)"
+        self.check(b, a)
+
+    def test_bare_isCallable(self):
+        s = "isCallable(x)"
+        t = "You should use 'hasattr(x, '__call__')' here."
+        self.warns_unchanged(s, t)
+
+    def test_bare_sequenceIncludes(self):
+        s = "sequenceIncludes(x, y)"
+        t = "You should use 'operator.contains(x, y)' here."
+        self.warns_unchanged(s, t)
+
+    def test_bare_operator_isSequenceType(self):
+        s = "isSequenceType(z)"
+        t = "You should use 'isinstance(z, collections.Sequence)' here."
+        self.warns_unchanged(s, t)
+
+    def test_bare_operator_isMappingType(self):
+        s = "isMappingType(x)"
+        t = "You should use 'isinstance(x, collections.Mapping)' here."
+        self.warns_unchanged(s, t)
+
+    def test_bare_operator_isNumberType(self):
+        s = "isNumberType(y)"
+        t = "You should use 'isinstance(y, numbers.Number)' here."
+        self.warns_unchanged(s, t)
+
+    def test_bare_operator_repeat(self):
+        s = "repeat(x, n)"
+        t = "You should use 'operator.mul(x, n)' here."
+        self.warns_unchanged(s, t)
+
+    def test_bare_operator_irepeat(self):
+        s = "irepeat(y, 187)"
+        t = "You should use 'operator.imul(y, 187)' here."
+        self.warns_unchanged(s, t)
+
+
+class Test_exitfunc(FixerTestCase):
+
+    fixer = "exitfunc"
+
+    def test_simple(self):
+        b = """
+            import sys
+            sys.exitfunc = my_atexit
+            """
+        a = """
+            import sys
+            import atexit
+            atexit.register(my_atexit)
+            """
+        self.check(b, a)
+
+    def test_names_import(self):
+        b = """
+            import sys, crumbs
+            sys.exitfunc = my_func
+            """
+        a = """
+            import sys, crumbs, atexit
+            atexit.register(my_func)
+            """
+        self.check(b, a)
+
+    def test_complex_expression(self):
+        b = """
+            import sys
+            sys.exitfunc = do(d)/a()+complex(f=23, g=23)*expression
+            """
+        a = """
+            import sys
+            import atexit
+            atexit.register(do(d)/a()+complex(f=23, g=23)*expression)
+            """
+        self.check(b, a)
+
+    def test_comments(self):
+        b = """
+            import sys # Foo
+            sys.exitfunc = f # Blah
+            """
+        a = """
+            import sys
+            import atexit # Foo
+            atexit.register(f) # Blah
+            """
+        self.check(b, a)
+
+        b = """
+            import apples, sys, crumbs, larry # Pleasant comments
+            sys.exitfunc = func
+            """
+        a = """
+            import apples, sys, crumbs, larry, atexit # Pleasant comments
+            atexit.register(func)
+            """
+        self.check(b, a)
+
+    def test_in_a_function(self):
+        b = """
+            import sys
+            def f():
+                sys.exitfunc = func
+            """
+        a = """
+            import sys
+            import atexit
+            def f():
+                atexit.register(func)
+             """
+        self.check(b, a)
+
+    def test_no_sys_import(self):
+        b = """sys.exitfunc = f"""
+        a = """atexit.register(f)"""
+        msg = ("Can't find sys import; Please add an atexit import at the "
+            "top of your file.")
+        self.warns(b, a, msg)
+
+
+    def test_unchanged(self):
+        s = """f(sys.exitfunc)"""
+        self.unchanged(s)
diff --git a/lib3/2to3/lib2to3/tests/test_main.py b/lib3/2to3/lib2to3/tests/test_main.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/test_main.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+import sys
+import codecs
+import logging
+import io
+import unittest
+
+from lib2to3 import main
+
+
+class TestMain(unittest.TestCase):
+
+    def tearDown(self):
+        # Clean up logging configuration down by main.
+        del logging.root.handlers[:]
+
+    def run_2to3_capture(self, args, in_capture, out_capture, err_capture):
+        save_stdin = sys.stdin
+        save_stdout = sys.stdout
+        save_stderr = sys.stderr
+        sys.stdin = in_capture
+        sys.stdout = out_capture
+        sys.stderr = err_capture
+        try:
+            return main.main("lib2to3.fixes", args)
+        finally:
+            sys.stdin = save_stdin
+            sys.stdout = save_stdout
+            sys.stderr = save_stderr
+
+    def test_unencodable_diff(self):
+        input_stream = io.StringIO("print 'nothing'\nprint u'über'\n")
+        out = io.StringIO()
+        out_enc = codecs.getwriter("ascii")(out)
+        err = io.StringIO()
+        ret = self.run_2to3_capture(["-"], input_stream, out_enc, err)
+        self.assertEqual(ret, 0)
+        output = out.getvalue()
+        self.assertTrue("-print 'nothing'" in output)
+        self.assertTrue("WARNING: couldn't encode <stdin>'s diff for "
+                        "your terminal" in err.getvalue())
diff --git a/lib3/2to3/lib2to3/tests/test_parser.py b/lib3/2to3/lib2to3/tests/test_parser.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/test_parser.py
@@ -0,0 +1,217 @@
+"""Test suite for 2to3's parser and grammar files.
+
+This is the place to add tests for changes to 2to3's grammar, such as those
+merging the grammars for Python 2 and 3. In addition to specific tests for
+parts of the grammar we've changed, we also make sure we can parse the
+test_grammar.py files from both Python 2 and Python 3.
+"""
+
+
+
+# Testing imports
+from . import support
+from .support import driver, test_dir
+
+# Python imports
+import os
+import sys
+
+# Local imports
+from lib2to3.pgen2 import tokenize
+from ..pgen2.parse import ParseError
+
+
+class GrammarTest(support.TestCase):
+    def validate(self, code):
+        support.parse_string(code)
+
+    def invalid_syntax(self, code):
+        try:
+            self.validate(code)
+        except ParseError:
+            pass
+        else:
+            raise AssertionError("Syntax shouldn't have been valid")
+
+
+class TestRaiseChanges(GrammarTest):
+    def test_2x_style_1(self):
+        self.validate("raise")
+
+    def test_2x_style_2(self):
+        self.validate("raise E, V")
+
+    def test_2x_style_3(self):
+        self.validate("raise E, V, T")
+
+    def test_2x_style_invalid_1(self):
+        self.invalid_syntax("raise E, V, T, Z")
+
+    def test_3x_style(self):
+        self.validate("raise E1 from E2")
+
+    def test_3x_style_invalid_1(self):
+        self.invalid_syntax("raise E, V from E1")
+
+    def test_3x_style_invalid_2(self):
+        self.invalid_syntax("raise E from E1, E2")
+
+    def test_3x_style_invalid_3(self):
+        self.invalid_syntax("raise from E1, E2")
+
+    def test_3x_style_invalid_4(self):
+        self.invalid_syntax("raise E from")
+
+
+# Adapated from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef
+class TestFunctionAnnotations(GrammarTest):
+    def test_1(self):
+        self.validate("""def f(x) -> list: pass""")
+
+    def test_2(self):
+        self.validate("""def f(x:int): pass""")
+
+    def test_3(self):
+        self.validate("""def f(*x:str): pass""")
+
+    def test_4(self):
+        self.validate("""def f(**x:float): pass""")
+
+    def test_5(self):
+        self.validate("""def f(x, y:1+2): pass""")
+
+    def test_6(self):
+        self.validate("""def f(a, (b:1, c:2, d)): pass""")
+
+    def test_7(self):
+        self.validate("""def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass""")
+
+    def test_8(self):
+        s = """def f(a, (b:1, c:2, d), e:3=4, f=5,
+                        *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass"""
+        self.validate(s)
+
+
+class TestExcept(GrammarTest):
+    def test_new(self):
+        s = """
+            try:
+                x
+            except E as N:
+                y"""
+        self.validate(s)
+
+    def test_old(self):
+        s = """
+            try:
+                x
+            except E, N:
+                y"""
+        self.validate(s)
+
+
+# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testAtoms
+class TestSetLiteral(GrammarTest):
+    def test_1(self):
+        self.validate("""x = {'one'}""")
+
+    def test_2(self):
+        self.validate("""x = {'one', 1,}""")
+
+    def test_3(self):
+        self.validate("""x = {'one', 'two', 'three'}""")
+
+    def test_4(self):
+        self.validate("""x = {2, 3, 4,}""")
+
+
+class TestNumericLiterals(GrammarTest):
+    def test_new_octal_notation(self):
+        self.validate("""0o7777777777777""")
+        self.invalid_syntax("""0o7324528887""")
+
+    def test_new_binary_notation(self):
+        self.validate("""0b101010""")
+        self.invalid_syntax("""0b0101021""")
+
+
+class TestClassDef(GrammarTest):
+    def test_new_syntax(self):
+        self.validate("class B(t=7): pass")
+        self.validate("class B(t, *args): pass")
+        self.validate("class B(t, **kwargs): pass")
+        self.validate("class B(t, *args, **kwargs): pass")
+        self.validate("class B(t, y=9, *args, **kwargs): pass")
+
+
+class TestParserIdempotency(support.TestCase):
+
+    """A cut-down version of pytree_idempotency.py."""
+
+    def test_all_project_files(self):
+        if sys.platform.startswith("win"):
+            # XXX something with newlines goes wrong on Windows.
+            return
+        for filepath in support.all_project_files():
+            with open(filepath, "rb") as fp:
+                encoding = tokenize.detect_encoding(fp.readline)[0]
+            self.assertTrue(encoding is not None,
+                            "can't detect encoding for %s" % filepath)
+            with open(filepath, "r") as fp:
+                source = fp.read()
+                source = source.decode(encoding)
+            tree = driver.parse_string(source)
+            new = str(tree)
+            if diff(filepath, new, encoding):
+                self.fail("Idempotency failed: %s" % filepath)
+
+    def test_extended_unpacking(self):
+        driver.parse_string("a, *b, c = x\n")
+        driver.parse_string("[*a, b] = x\n")
+        driver.parse_string("(z, *y, w) = m\n")
+        driver.parse_string("for *z, m in d: pass\n")
+
+class TestLiterals(GrammarTest):
+
+    def validate(self, s):
+        driver.parse_string(support.dedent(s) + "\n\n")
+
+    def test_multiline_bytes_literals(self):
+        s = """
+            md5test(b"\xaa" * 80,
+                    (b"Test Using Larger Than Block-Size Key "
+                     b"and Larger Than One Block-Size Data"),
+                    "6f630fad67cda0ee1fb1f562db3aa53e")
+            """
+        self.validate(s)
+
+    def test_multiline_bytes_tripquote_literals(self):
+        s = '''
+            b"""
+            <?xml version="1.0" encoding="UTF-8"?>
+            <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN">
+            """
+            '''
+        self.validate(s)
+
+    def test_multiline_str_literals(self):
+        s = """
+            md5test("\xaa" * 80,
+                    ("Test Using Larger Than Block-Size Key "
+                     "and Larger Than One Block-Size Data"),
+                    "6f630fad67cda0ee1fb1f562db3aa53e")
+            """
+        self.validate(s)
+
+
+def diff(fn, result, encoding):
+    f = open("@", "w")
+    try:
+        f.write(result.encode(encoding))
+    finally:
+        f.close()
+    try:
+        fn = fn.replace('"', '\\"')
+        return os.system('diff -u "%s" @' % fn)
+    finally:
+        os.remove("@")
diff --git a/lib3/2to3/lib2to3/tests/test_pytree.py b/lib3/2to3/lib2to3/tests/test_pytree.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/test_pytree.py
@@ -0,0 +1,494 @@
+# Copyright 2006 Google, Inc. All Rights Reserved.
+# Licensed to PSF under a Contributor Agreement.
+
+"""Unit tests for pytree.py.
+
+NOTE: Please *don't* add doc strings to individual test methods!
+In verbose mode, printing of the module, class and method name is much
+more helpful than printing of (the first line of) the docstring,
+especially when debugging a test.
+"""
+
+
+
+import sys
+import warnings
+
+# Testing imports
+from . import support
+
+from lib2to3 import pytree
+
+try:
+    sorted
+except NameError:
+    def sorted(lst):
+        l = list(lst)
+        l.sort()
+        return l
+
+class TestNodes(support.TestCase):
+
+    """Unit tests for nodes (Base, Leaf, Node)."""
+
+    if sys.version_info >= (2,6):
+        # warnings.catch_warnings is new in 2.6.
+        def test_deprecated_prefix_methods(self):
+            l = pytree.Leaf(100, "foo")
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter("always", DeprecationWarning)
+                self.assertEqual(l.get_prefix(), "")
+                l.set_prefix("hi")
+            self.assertEqual(l.prefix, "hi")
+            self.assertEqual(len(w), 2)
+            for warning in w:
+                self.assertTrue(warning.category is DeprecationWarning)
+            self.assertEqual(str(w[0].message), "get_prefix() is deprecated; " \
+                                 "use the prefix property")
+            self.assertEqual(str(w[1].message), "set_prefix() is deprecated; " \
+                                 "use the prefix property")
+
+    def test_instantiate_base(self):
+        if __debug__:
+            # Test that instantiating Base() raises an AssertionError
+            self.assertRaises(AssertionError, pytree.Base)
+
+    def test_leaf(self):
+        l1 = pytree.Leaf(100, "foo")
+        self.assertEqual(l1.type, 100)
+        self.assertEqual(l1.value, "foo")
+
+    def test_leaf_repr(self):
+        l1 = pytree.Leaf(100, "foo")
+        self.assertEqual(repr(l1), "Leaf(100, 'foo')")
+
+    def test_leaf_str(self):
+        l1 = pytree.Leaf(100, "foo")
+        self.assertEqual(str(l1), "foo")
+        l2 = pytree.Leaf(100, "foo", context=(" ", (10, 1)))
+        self.assertEqual(str(l2), " foo")
+
+    def test_leaf_str_numeric_value(self):
+        # Make sure that the Leaf's value is stringified. Failing to
+        #  do this can cause a TypeError in certain situations.
+        l1 = pytree.Leaf(2, 5)
+        l1.prefix = "foo_"
+        self.assertEqual(str(l1), "foo_5")
+
+    def test_leaf_equality(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "foo", context=(" ", (1, 0)))
+        self.assertEqual(l1, l2)
+        l3 = pytree.Leaf(101, "foo")
+        l4 = pytree.Leaf(100, "bar")
+        self.assertNotEqual(l1, l3)
+        self.assertNotEqual(l1, l4)
+
+    def test_leaf_prefix(self):
+        l1 = pytree.Leaf(100, "foo")
+        self.assertEqual(l1.prefix, "")
+        self.assertFalse(l1.was_changed)
+        l1.prefix = "  ##\n\n"
+        self.assertEqual(l1.prefix, "  ##\n\n")
+        self.assertTrue(l1.was_changed)
+
+    def test_node(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(200, "bar")
+        n1 = pytree.Node(1000, [l1, l2])
+        self.assertEqual(n1.type, 1000)
+        self.assertEqual(n1.children, [l1, l2])
+
+    def test_node_repr(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0)))
+        n1 = pytree.Node(1000, [l1, l2])
+        self.assertEqual(repr(n1),
+                         "Node(1000, [%s, %s])" % (repr(l1), repr(l2)))
+
+    def test_node_str(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0)))
+        n1 = pytree.Node(1000, [l1, l2])
+        self.assertEqual(str(n1), "foo bar")
+
+    def test_node_prefix(self):
+        l1 = pytree.Leaf(100, "foo")
+        self.assertEqual(l1.prefix, "")
+        n1 = pytree.Node(1000, [l1])
+        self.assertEqual(n1.prefix, "")
+        n1.prefix = " "
+        self.assertEqual(n1.prefix, " ")
+        self.assertEqual(l1.prefix, " ")
+
+    def test_get_suffix(self):
+        l1 = pytree.Leaf(100, "foo", prefix="a")
+        l2 = pytree.Leaf(100, "bar", prefix="b")
+        n1 = pytree.Node(1000, [l1, l2])
+
+        self.assertEqual(l1.get_suffix(), l2.prefix)
+        self.assertEqual(l2.get_suffix(), "")
+        self.assertEqual(n1.get_suffix(), "")
+
+        l3 = pytree.Leaf(100, "bar", prefix="c")
+        n2 = pytree.Node(1000, [n1, l3])
+
+        self.assertEqual(n1.get_suffix(), l3.prefix)
+        self.assertEqual(l3.get_suffix(), "")
+        self.assertEqual(n2.get_suffix(), "")
+
+    def test_node_equality(self):
+        n1 = pytree.Node(1000, ())
+        n2 = pytree.Node(1000, [], context=(" ", (1, 0)))
+        self.assertEqual(n1, n2)
+        n3 = pytree.Node(1001, ())
+        self.assertNotEqual(n1, n3)
+
+    def test_node_recursive_equality(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "foo")
+        n1 = pytree.Node(1000, [l1])
+        n2 = pytree.Node(1000, [l2])
+        self.assertEqual(n1, n2)
+        l3 = pytree.Leaf(100, "bar")
+        n3 = pytree.Node(1000, [l3])
+        self.assertNotEqual(n1, n3)
+
+    def test_replace(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "+")
+        l3 = pytree.Leaf(100, "bar")
+        n1 = pytree.Node(1000, [l1, l2, l3])
+        self.assertEqual(n1.children, [l1, l2, l3])
+        self.assertTrue(isinstance(n1.children, list))
+        self.assertFalse(n1.was_changed)
+        l2new = pytree.Leaf(100, "-")
+        l2.replace(l2new)
+        self.assertEqual(n1.children, [l1, l2new, l3])
+        self.assertTrue(isinstance(n1.children, list))
+        self.assertTrue(n1.was_changed)
+
+    def test_replace_with_list(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "+")
+        l3 = pytree.Leaf(100, "bar")
+        n1 = pytree.Node(1000, [l1, l2, l3])
+
+        l2.replace([pytree.Leaf(100, "*"), pytree.Leaf(100, "*")])
+        self.assertEqual(str(n1), "foo**bar")
+        self.assertTrue(isinstance(n1.children, list))
+
+    def test_leaves(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "bar")
+        l3 = pytree.Leaf(100, "fooey")
+        n2 = pytree.Node(1000, [l1, l2])
+        n3 = pytree.Node(1000, [l3])
+        n1 = pytree.Node(1000, [n2, n3])
+
+        self.assertEqual(list(n1.leaves()), [l1, l2, l3])
+
+    def test_depth(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "bar")
+        n2 = pytree.Node(1000, [l1, l2])
+        n3 = pytree.Node(1000, [])
+        n1 = pytree.Node(1000, [n2, n3])
+
+        self.assertEqual(l1.depth(), 2)
+        self.assertEqual(n3.depth(), 1)
+        self.assertEqual(n1.depth(), 0)
+
+    def test_post_order(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "bar")
+        l3 = pytree.Leaf(100, "fooey")
+        c1 = pytree.Node(1000, [l1, l2])
+        n1 = pytree.Node(1000, [c1, l3])
+        self.assertEqual(list(n1.post_order()), [l1, l2, c1, l3, n1])
+
+    def test_pre_order(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "bar")
+        l3 = pytree.Leaf(100, "fooey")
+        c1 = pytree.Node(1000, [l1, l2])
+        n1 = pytree.Node(1000, [c1, l3])
+        self.assertEqual(list(n1.pre_order()), [n1, c1, l1, l2, l3])
+
+    def test_changed(self):
+        l1 = pytree.Leaf(100, "f")
+        self.assertFalse(l1.was_changed)
+        l1.changed()
+        self.assertTrue(l1.was_changed)
+
+        l1 = pytree.Leaf(100, "f")
+        n1 = pytree.Node(1000, [l1])
+        self.assertFalse(n1.was_changed)
+        n1.changed()
+        self.assertTrue(n1.was_changed)
+
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "+")
+        l3 = pytree.Leaf(100, "bar")
+        n1 = pytree.Node(1000, [l1, l2, l3])
+        n2 = pytree.Node(1000, [n1])
+        self.assertFalse(l1.was_changed)
+        self.assertFalse(n1.was_changed)
+        self.assertFalse(n2.was_changed)
+
+        n1.changed()
+        self.assertTrue(n1.was_changed)
+        self.assertTrue(n2.was_changed)
+        self.assertFalse(l1.was_changed)
+
+    def test_leaf_constructor_prefix(self):
+        for prefix in ("xyz_", ""):
+            l1 = pytree.Leaf(100, "self", prefix=prefix)
+            self.assertTrue(str(l1), prefix + "self")
+            self.assertEqual(l1.prefix, prefix)
+
+    def test_node_constructor_prefix(self):
+        for prefix in ("xyz_", ""):
+            l1 = pytree.Leaf(100, "self")
+            l2 = pytree.Leaf(100, "foo", prefix="_")
+            n1 = pytree.Node(1000, [l1, l2], prefix=prefix)
+            self.assertTrue(str(n1), prefix + "self_foo")
+            self.assertEqual(n1.prefix, prefix)
+            self.assertEqual(l1.prefix, prefix)
+            self.assertEqual(l2.prefix, "_")
+
+    def test_remove(self):
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "foo")
+        n1 = pytree.Node(1000, [l1, l2])
+        n2 = pytree.Node(1000, [n1])
+
+        self.assertEqual(n1.remove(), 0)
+        self.assertEqual(n2.children, [])
+        self.assertEqual(l1.parent, n1)
+        self.assertEqual(n1.parent, None)
+        self.assertEqual(n2.parent, None)
+        self.assertFalse(n1.was_changed)
+        self.assertTrue(n2.was_changed)
+
+        self.assertEqual(l2.remove(), 1)
+        self.assertEqual(l1.remove(), 0)
+        self.assertEqual(n1.children, [])
+        self.assertEqual(l1.parent, None)
+        self.assertEqual(n1.parent, None)
+        self.assertEqual(n2.parent, None)
+        self.assertTrue(n1.was_changed)
+        self.assertTrue(n2.was_changed)
+
+    def test_remove_parentless(self):
+        n1 = pytree.Node(1000, [])
+        n1.remove()
+        self.assertEqual(n1.parent, None)
+
+        l1 = pytree.Leaf(100, "foo")
+        l1.remove()
+        self.assertEqual(l1.parent, None)
+
+    def test_node_set_child(self):
+        l1 = pytree.Leaf(100, "foo")
+        n1 = pytree.Node(1000, [l1])
+
+        l2 = pytree.Leaf(100, "bar")
+        n1.set_child(0, l2)
+        self.assertEqual(l1.parent, None)
+        self.assertEqual(l2.parent, n1)
+        self.assertEqual(n1.children, [l2])
+
+        n2 = pytree.Node(1000, [l1])
+        n2.set_child(0, n1)
+        self.assertEqual(l1.parent, None)
+        self.assertEqual(n1.parent, n2)
+        self.assertEqual(n2.parent, None)
+        self.assertEqual(n2.children, [n1])
+
+        self.assertRaises(IndexError, n1.set_child, 4, l2)
+        # I don't care what it raises, so long as it's an exception
+        self.assertRaises(Exception, n1.set_child, 0, list)
+
+    def test_node_insert_child(self):
+        l1 = pytree.Leaf(100, "foo")
+        n1 = pytree.Node(1000, [l1])
+
+        l2 = pytree.Leaf(100, "bar")
+        n1.insert_child(0, l2)
+        self.assertEqual(l2.parent, n1)
+        self.assertEqual(n1.children, [l2, l1])
+
+        l3 = pytree.Leaf(100, "abc")
+        n1.insert_child(2, l3)
+        self.assertEqual(n1.children, [l2, l1, l3])
+
+        # I don't care what it raises, so long as it's an exception
+        self.assertRaises(Exception, n1.insert_child, 0, list)
+
+    def test_node_append_child(self):
+        n1 = pytree.Node(1000, [])
+
+        l1 = pytree.Leaf(100, "foo")
+        n1.append_child(l1)
+        self.assertEqual(l1.parent, n1)
+        self.assertEqual(n1.children, [l1])
+
+        l2 = pytree.Leaf(100, "bar")
+        n1.append_child(l2)
+        self.assertEqual(l2.parent, n1)
+        self.assertEqual(n1.children, [l1, l2])
+
+        # I don't care what it raises, so long as it's an exception
+        self.assertRaises(Exception, n1.append_child, list)
+
+    def test_node_next_sibling(self):
+        n1 = pytree.Node(1000, [])
+        n2 = pytree.Node(1000, [])
+        p1 = pytree.Node(1000, [n1, n2])
+
+        self.assertTrue(n1.next_sibling is n2)
+        self.assertEqual(n2.next_sibling, None)
+        self.assertEqual(p1.next_sibling, None)
+
+    def test_leaf_next_sibling(self):
+        l1 = pytree.Leaf(100, "a")
+        l2 = pytree.Leaf(100, "b")
+        p1 = pytree.Node(1000, [l1, l2])
+
+        self.assertTrue(l1.next_sibling is l2)
+        self.assertEqual(l2.next_sibling, None)
+        self.assertEqual(p1.next_sibling, None)
+
+    def test_node_prev_sibling(self):
+        n1 = pytree.Node(1000, [])
+        n2 = pytree.Node(1000, [])
+        p1 = pytree.Node(1000, [n1, n2])
+
+        self.assertTrue(n2.prev_sibling is n1)
+        self.assertEqual(n1.prev_sibling, None)
+        self.assertEqual(p1.prev_sibling, None)
+
+    def test_leaf_prev_sibling(self):
+        l1 = pytree.Leaf(100, "a")
+        l2 = pytree.Leaf(100, "b")
+        p1 = pytree.Node(1000, [l1, l2])
+
+        self.assertTrue(l2.prev_sibling is l1)
+        self.assertEqual(l1.prev_sibling, None)
+        self.assertEqual(p1.prev_sibling, None)
+
+
+class TestPatterns(support.TestCase):
+
+    """Unit tests for tree matching patterns."""
+
+    def test_basic_patterns(self):
+        # Build a tree
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "bar")
+        l3 = pytree.Leaf(100, "foo")
+        n1 = pytree.Node(1000, [l1, l2])
+        n2 = pytree.Node(1000, [l3])
+        root = pytree.Node(1000, [n1, n2])
+        # Build a pattern matching a leaf
+        pl = pytree.LeafPattern(100, "foo", name="pl")
+        r = {}
+        self.assertFalse(pl.match(root, results=r))
+        self.assertEqual(r, {})
+        self.assertFalse(pl.match(n1, results=r))
+        self.assertEqual(r, {})
+        self.assertFalse(pl.match(n2, results=r))
+        self.assertEqual(r, {})
+        self.assertTrue(pl.match(l1, results=r))
+        self.assertEqual(r, {"pl": l1})
+        r = {}
+        self.assertFalse(pl.match(l2, results=r))
+        self.assertEqual(r, {})
+        # Build a pattern matching a node
+        pn = pytree.NodePattern(1000, [pl], name="pn")
+        self.assertFalse(pn.match(root, results=r))
+        self.assertEqual(r, {})
+        self.assertFalse(pn.match(n1, results=r))
+        self.assertEqual(r, {})
+        self.assertTrue(pn.match(n2, results=r))
+        self.assertEqual(r, {"pn": n2, "pl": l3})
+        r = {}
+        self.assertFalse(pn.match(l1, results=r))
+        self.assertEqual(r, {})
+        self.assertFalse(pn.match(l2, results=r))
+        self.assertEqual(r, {})
+
+    def test_wildcard(self):
+        # Build a tree for testing
+        l1 = pytree.Leaf(100, "foo")
+        l2 = pytree.Leaf(100, "bar")
+        l3 = pytree.Leaf(100, "foo")
+        n1 = pytree.Node(1000, [l1, l2])
+        n2 = pytree.Node(1000, [l3])
+        root = pytree.Node(1000, [n1, n2])
+        # Build a pattern
+        pl = pytree.LeafPattern(100, "foo", name="pl")
+        pn = pytree.NodePattern(1000, [pl], name="pn")
+        pw = pytree.WildcardPattern([[pn], [pl, pl]], name="pw")
+        r = {}
+        self.assertFalse(pw.match_seq([root], r))
+        self.assertEqual(r, {})
+        self.assertFalse(pw.match_seq([n1], r))
+        self.assertEqual(r, {})
+        self.assertTrue(pw.match_seq([n2], r))
+        # These are easier to debug
+        self.assertEqual(sorted(r.keys()), ["pl", "pn", "pw"])
+        self.assertEqual(r["pl"], l1)
+        self.assertEqual(r["pn"], n2)
+        self.assertEqual(r["pw"], [n2])
+        # But this is equivalent
+        self.assertEqual(r, {"pl": l1, "pn": n2, "pw": [n2]})
+        r = {}
+        self.assertTrue(pw.match_seq([l1, l3], r))
+        self.assertEqual(r, {"pl": l3, "pw": [l1, l3]})
+        self.assertTrue(r["pl"] is l3)
+        r = {}
+
+    def test_generate_matches(self):
+        la = pytree.Leaf(1, "a")
+        lb = pytree.Leaf(1, "b")
+        lc = pytree.Leaf(1, "c")
+        ld = pytree.Leaf(1, "d")
+        le = pytree.Leaf(1, "e")
+        lf = pytree.Leaf(1, "f")
+        leaves = [la, lb, lc, ld, le, lf]
+        root = pytree.Node(1000, leaves)
+        pa = pytree.LeafPattern(1, "a", "pa")
+        pb = pytree.LeafPattern(1, "b", "pb")
+        pc = pytree.LeafPattern(1, "c", "pc")
+        pd = pytree.LeafPattern(1, "d", "pd")
+        pe = pytree.LeafPattern(1, "e", "pe")
+        pf = pytree.LeafPattern(1, "f", "pf")
+        pw = pytree.WildcardPattern([[pa, pb, pc], [pd, pe],
+                                     [pa, pb], [pc, pd], [pe, pf]],
+                                    min=1, max=4, name="pw")
+        self.assertEqual([x[0] for x in pw.generate_matches(leaves)],
+                         [3, 5, 2, 4, 6])
+        pr = pytree.NodePattern(type=1000, content=[pw], name="pr")
+        matches = list(pytree.generate_matches([pr], [root]))
+        self.assertEqual(len(matches), 1)
+        c, r = matches[0]
+        self.assertEqual(c, 1)
+        self.assertEqual(str(r["pr"]), "abcdef")
+        self.assertEqual(r["pw"], [la, lb, lc, ld, le, lf])
+        for c in "abcdef":
+            self.assertEqual(r["p" + c], pytree.Leaf(1, c))
+
+    def test_has_key_example(self):
+        pattern = pytree.NodePattern(331,
+                                     (pytree.LeafPattern(7),
+                                      pytree.WildcardPattern(name="args"),
+                                      pytree.LeafPattern(8)))
+        l1 = pytree.Leaf(7, "(")
+        l2 = pytree.Leaf(3, "x")
+        l3 = pytree.Leaf(8, ")")
+        node = pytree.Node(331, [l1, l2, l3])
+        r = {}
+        self.assertTrue(pattern.match(node, r))
+        self.assertEqual(r["args"], [l2])
diff --git a/lib3/2to3/lib2to3/tests/test_refactor.py b/lib3/2to3/lib2to3/tests/test_refactor.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/test_refactor.py
@@ -0,0 +1,281 @@
+"""
+Unit tests for refactor.py.
+"""
+
+
+
+import sys
+import os
+import codecs
+import operator
+import io
+import tempfile
+import shutil
+import unittest
+import warnings
+
+from lib2to3 import refactor, pygram, fixer_base
+from lib2to3.pgen2 import token
+
+from . import support
+
+
+TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
+FIXER_DIR = os.path.join(TEST_DATA_DIR, "fixers")
+
+sys.path.append(FIXER_DIR)
+try:
+    _DEFAULT_FIXERS = refactor.get_fixers_from_package("myfixes")
+finally:
+    sys.path.pop()
+
+_2TO3_FIXERS = refactor.get_fixers_from_package("lib2to3.fixes")
+
+class TestRefactoringTool(unittest.TestCase):
+
+    def setUp(self):
+        sys.path.append(FIXER_DIR)
+
+    def tearDown(self):
+        sys.path.pop()
+
+    def check_instances(self, instances, classes):
+        for inst, cls in zip(instances, classes):
+            if not isinstance(inst, cls):
+                self.fail("%s are not instances of %s" % instances, classes)
+
+    def rt(self, options=None, fixers=_DEFAULT_FIXERS, explicit=None):
+        return refactor.RefactoringTool(fixers, options, explicit)
+
+    def test_print_function_option(self):
+        rt = self.rt({"print_function" : True})
+        self.assertTrue(rt.grammar is pygram.python_grammar_no_print_statement)
+        self.assertTrue(rt.driver.grammar is
+                        pygram.python_grammar_no_print_statement)
+
+    def test_fixer_loading_helpers(self):
+        contents = ["explicit", "first", "last", "parrot", "preorder"]
+        non_prefixed = refactor.get_all_fix_names("myfixes")
+        prefixed = refactor.get_all_fix_names("myfixes", False)
+        full_names = refactor.get_fixers_from_package("myfixes")
+        self.assertEqual(prefixed, ["fix_" + name for name in contents])
+        self.assertEqual(non_prefixed, contents)
+        self.assertEqual(full_names,
+                         ["myfixes.fix_" + name for name in contents])
+
+    def test_detect_future_features(self):
+        run = refactor._detect_future_features
+        fs = frozenset
+        empty = fs()
+        self.assertEqual(run(""), empty)
+        self.assertEqual(run("from __future__ import print_function"),
+                         fs(("print_function",)))
+        self.assertEqual(run("from __future__ import generators"),
+                         fs(("generators",)))
+        self.assertEqual(run("from __future__ import generators, feature"),
+                         fs(("generators", "feature")))
+        inp = "from __future__ import generators, print_function"
+        self.assertEqual(run(inp), fs(("generators", "print_function")))
+        inp ="from __future__ import print_function, generators"
+        self.assertEqual(run(inp), fs(("print_function", "generators")))
+        inp = "from __future__ import (print_function,)"
+        self.assertEqual(run(inp), fs(("print_function",)))
+        inp = "from __future__ import (generators, print_function)"
+        self.assertEqual(run(inp), fs(("generators", "print_function")))
+        inp = "from __future__ import (generators, nested_scopes)"
+        self.assertEqual(run(inp), fs(("generators", "nested_scopes")))
+        inp = """from __future__ import generators
+from __future__ import print_function"""
+        self.assertEqual(run(inp), fs(("generators", "print_function")))
+        invalid = ("from",
+                   "from 4",
+                   "from x",
+                   "from x 5",
+                   "from x im",
+                   "from x import",
+                   "from x import 4",
+                   )
+        for inp in invalid:
+            self.assertEqual(run(inp), empty)
+        inp = "'docstring'\nfrom __future__ import print_function"
+        self.assertEqual(run(inp), fs(("print_function",)))
+        inp = "'docstring'\n'somng'\nfrom __future__ import print_function"
+        self.assertEqual(run(inp), empty)
+        inp = "# comment\nfrom __future__ import print_function"
+        self.assertEqual(run(inp), fs(("print_function",)))
+        inp = "# comment\n'doc'\nfrom __future__ import print_function"
+        self.assertEqual(run(inp), fs(("print_function",)))
+        inp = "class x: pass\nfrom __future__ import print_function"
+        self.assertEqual(run(inp), empty)
+
+    def test_get_headnode_dict(self):
+        class NoneFix(fixer_base.BaseFix):
+            pass
+
+        class FileInputFix(fixer_base.BaseFix):
+            PATTERN = "file_input< any * >"
+
+        class SimpleFix(fixer_base.BaseFix):
+            PATTERN = "'name'"
+
+        no_head = NoneFix({}, [])
+        with_head = FileInputFix({}, [])
+        simple = SimpleFix({}, [])
+        d = refactor._get_headnode_dict([no_head, with_head, simple])
+        top_fixes = d.pop(pygram.python_symbols.file_input)
+        self.assertEqual(top_fixes, [with_head, no_head])
+        name_fixes = d.pop(token.NAME)
+        self.assertEqual(name_fixes, [simple, no_head])
+        for fixes in d.values():
+            self.assertEqual(fixes, [no_head])
+
+    def test_fixer_loading(self):
+        from myfixes.fix_first import FixFirst
+        from myfixes.fix_last import FixLast
+        from myfixes.fix_parrot import FixParrot
+        from myfixes.fix_preorder import FixPreorder
+
+        rt = self.rt()
+        pre, post = rt.get_fixers()
+
+        self.check_instances(pre, [FixPreorder])
+        self.check_instances(post, [FixFirst, FixParrot, FixLast])
+
+    def test_naughty_fixers(self):
+        self.assertRaises(ImportError, self.rt, fixers=["not_here"])
+        self.assertRaises(refactor.FixerError, self.rt, fixers=["no_fixer_cls"])
+        self.assertRaises(refactor.FixerError, self.rt, fixers=["bad_order"])
+
+    def test_refactor_string(self):
+        rt = self.rt()
+        input = "def parrot(): pass\n\n"
+        tree = rt.refactor_string(input, "<test>")
+        self.assertNotEqual(str(tree), input)
+
+        input = "def f(): pass\n\n"
+        tree = rt.refactor_string(input, "<test>")
+        self.assertEqual(str(tree), input)
+
+    def test_refactor_stdin(self):
+
+        class MyRT(refactor.RefactoringTool):
+
+            def print_output(self, old_text, new_text, filename, equal):
+                results.extend([old_text, new_text, filename, equal])
+
+        results = []
+        rt = MyRT(_DEFAULT_FIXERS)
+        save = sys.stdin
+        sys.stdin = io.StringIO("def parrot(): pass\n\n")
+        try:
+            rt.refactor_stdin()
+        finally:
+            sys.stdin = save
+        expected = ["def parrot(): pass\n\n",
+                    "def cheese(): pass\n\n",
+                    "<stdin>", False]
+        self.assertEqual(results, expected)
+
+    def check_file_refactoring(self, test_file, fixers=_2TO3_FIXERS):
+        def read_file():
+            with open(test_file, "rb") as fp:
+                return fp.read()
+        old_contents = read_file()
+        rt = self.rt(fixers=fixers)
+
+        rt.refactor_file(test_file)
+        self.assertEqual(old_contents, read_file())
+
+        try:
+            rt.refactor_file(test_file, True)
+            new_contents = read_file()
+            self.assertNotEqual(old_contents, new_contents)
+        finally:
+            with open(test_file, "wb") as fp:
+                fp.write(old_contents)
+        return new_contents
+
+    def test_refactor_file(self):
+        test_file = os.path.join(FIXER_DIR, "parrot_example.py")
+        self.check_file_refactoring(test_file, _DEFAULT_FIXERS)
+
+    def test_refactor_dir(self):
+        def check(structure, expected):
+            def mock_refactor_file(self, f, *args):
+                got.append(f)
+            save_func = refactor.RefactoringTool.refactor_file
+            refactor.RefactoringTool.refactor_file = mock_refactor_file
+            rt = self.rt()
+            got = []
+            dir = tempfile.mkdtemp(prefix="2to3-test_refactor")
+            try:
+                os.mkdir(os.path.join(dir, "a_dir"))
+                for fn in structure:
+                    open(os.path.join(dir, fn), "wb").close()
+                rt.refactor_dir(dir)
+            finally:
+                refactor.RefactoringTool.refactor_file = save_func
+                shutil.rmtree(dir)
+            self.assertEqual(got,
+                             [os.path.join(dir, path) for path in expected])
+        check([], [])
+        tree = ["nothing",
+                "hi.py",
+                ".dumb",
+                ".after.py",
+                "notpy.npy",
+                "sappy"]
+        expected = ["hi.py"]
+        check(tree, expected)
+        tree = ["hi.py",
+                os.path.join("a_dir", "stuff.py")]
+        check(tree, tree)
+
+    def test_file_encoding(self):
+        fn = os.path.join(TEST_DATA_DIR, "different_encoding.py")
+        self.check_file_refactoring(fn)
+
+    def test_bom(self):
+        fn = os.path.join(TEST_DATA_DIR, "bom.py")
+        data = self.check_file_refactoring(fn)
+        self.assertTrue(data.startswith(codecs.BOM_UTF8))
+
+    def test_crlf_newlines(self):
+        old_sep = os.linesep
+        os.linesep = "\r\n"
+        try:
+            fn = os.path.join(TEST_DATA_DIR, "crlf.py")
+            fixes = refactor.get_fixers_from_package("lib2to3.fixes")
+            self.check_file_refactoring(fn, fixes)
+        finally:
+            os.linesep = old_sep
+
+    def test_refactor_docstring(self):
+        rt = self.rt()
+
+        doc = """
+>>> example()
+42
+"""
+        out = rt.refactor_docstring(doc, "<test>")
+        self.assertEqual(out, doc)
+
+        doc = """
+>>> def parrot():
+...      return 43
+"""
+        out = rt.refactor_docstring(doc, "<test>")
+        self.assertNotEqual(out, doc)
+
+    def test_explicit(self):
+        from myfixes.fix_explicit import FixExplicit
+
+        rt = self.rt(fixers=["myfixes.fix_explicit"])
+        self.assertEqual(len(rt.post_order), 0)
+
+        rt = self.rt(explicit=["myfixes.fix_explicit"])
+        for fix in rt.post_order:
+            if isinstance(fix, FixExplicit):
+                break
+        else:
+            self.fail("explicit fixer not loaded")
diff --git a/lib3/2to3/lib2to3/tests/test_util.py b/lib3/2to3/lib2to3/tests/test_util.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/lib2to3/tests/test_util.py
@@ -0,0 +1,594 @@
+""" Test suite for the code in fixer_util """
+
+# Testing imports
+from . import support
+
+# Python imports
+import os.path
+
+# Local imports
+from lib2to3.pytree import Node, Leaf
+from lib2to3 import fixer_util
+from lib2to3.fixer_util import Attr, Name, Call, Comma
+from lib2to3.pgen2 import token
+
+def parse(code, strip_levels=0):
+    # The topmost node is file_input, which we don't care about.
+    # The next-topmost node is a *_stmt node, which we also don't care about
+    tree = support.parse_string(code)
+    for i in range(strip_levels):
+        tree = tree.children[0]
+    tree.parent = None
+    return tree
+
+class MacroTestCase(support.TestCase):
+    def assertStr(self, node, string):
+        if isinstance(node, (tuple, list)):
+            node = Node(fixer_util.syms.simple_stmt, node)
+        self.assertEqual(str(node), string)
+
+
+class Test_is_tuple(support.TestCase):
+    def is_tuple(self, string):
+        return fixer_util.is_tuple(parse(string, strip_levels=2))
+
+    def test_valid(self):
+        self.assertTrue(self.is_tuple("(a, b)"))
+        self.assertTrue(self.is_tuple("(a, (b, c))"))
+        self.assertTrue(self.is_tuple("((a, (b, c)),)"))
+        self.assertTrue(self.is_tuple("(a,)"))
+        self.assertTrue(self.is_tuple("()"))
+
+    def test_invalid(self):
+        self.assertFalse(self.is_tuple("(a)"))
+        self.assertFalse(self.is_tuple("('foo') % (b, c)"))
+
+
+class Test_is_list(support.TestCase):
+    def is_list(self, string):
+        return fixer_util.is_list(parse(string, strip_levels=2))
+
+    def test_valid(self):
+        self.assertTrue(self.is_list("[]"))
+        self.assertTrue(self.is_list("[a]"))
+        self.assertTrue(self.is_list("[a, b]"))
+        self.assertTrue(self.is_list("[a, [b, c]]"))
+        self.assertTrue(self.is_list("[[a, [b, c]],]"))
+
+    def test_invalid(self):
+        self.assertFalse(self.is_list("[]+[]"))
+
+
+class Test_Attr(MacroTestCase):
+    def test(self):
+        call = parse("foo()", strip_levels=2)
+
+        self.assertStr(Attr(Name("a"), Name("b")), "a.b")
+        self.assertStr(Attr(call, Name("b")), "foo().b")
+
+    def test_returns(self):
+        attr = Attr(Name("a"), Name("b"))
+        self.assertEqual(type(attr), list)
+
+
+class Test_Name(MacroTestCase):
+    def test(self):
+        self.assertStr(Name("a"), "a")
+        self.assertStr(Name("foo.foo().bar"), "foo.foo().bar")
+        self.assertStr(Name("a", prefix="b"), "ba")
+
+
+class Test_Call(MacroTestCase):
+    def _Call(self, name, args=None, prefix=None):
+        """Help the next test"""
+        children = []
+        if isinstance(args, list):
+            for arg in args:
+                children.append(arg)
+                children.append(Comma())
+            children.pop()
+        return Call(Name(name), children, prefix)
+
+    def test(self):
+        kids = [None,
+                [Leaf(token.NUMBER, 1), Leaf(token.NUMBER, 2),
+                 Leaf(token.NUMBER, 3)],
+                [Leaf(token.NUMBER, 1), Leaf(token.NUMBER, 3),
+                 Leaf(token.NUMBER, 2), Leaf(token.NUMBER, 4)],
+                [Leaf(token.STRING, "b"), Leaf(token.STRING, "j", prefix=" ")]
+                ]
+        self.assertStr(self._Call("A"), "A()")
+        self.assertStr(self._Call("b", kids[1]), "b(1,2,3)")
+        self.assertStr(self._Call("a.b().c", kids[2]), "a.b().c(1,3,2,4)")
+        self.assertStr(self._Call("d", kids[3], prefix=" "), " d(b, j)")
+
+
+class Test_does_tree_import(support.TestCase):
+    def _find_bind_rec(self, name, node):
+        # Search a tree for a binding -- used to find the starting
+        # point for these tests.
+        c = fixer_util.find_binding(name, node)
+        if c: return c
+        for child in node.children:
+            c = self._find_bind_rec(name, child)
+            if c: return c
+
+    def does_tree_import(self, package, name, string):
+        node = parse(string)
+        # Find the binding of start -- that's what we'll go from
+        node = self._find_bind_rec('start', node)
+        return fixer_util.does_tree_import(package, name, node)
+
+    def try_with(self, string):
+        failing_tests = (("a", "a", "from a import b"),
+                         ("a.d", "a", "from a.d import b"),
+                         ("d.a", "a", "from d.a import b"),
+                         (None, "a", "import b"),
+                         (None, "a", "import b, c, d"))
+        for package, name, import_ in failing_tests:
+            n = self.does_tree_import(package, name, import_ + "\n" + string)
+            self.assertFalse(n)
+            n = self.does_tree_import(package, name, string + "\n" + import_)
+            self.assertFalse(n)
+
+        passing_tests = (("a", "a", "from a import a"),
+                         ("x", "a", "from x import a"),
+                         ("x", "a", "from x import b, c, a, d"),
+                         ("x.b", "a", "from x.b import a"),
+                         ("x.b", "a", "from x.b import b, c, a, d"),
+                         (None, "a", "import a"),
+                         (None, "a", "import b, c, a, d"))
+        for package, name, import_ in passing_tests:
+            n = self.does_tree_import(package, name, import_ + "\n" + string)
+            self.assertTrue(n)
+            n = self.does_tree_import(package, name, string + "\n" + import_)
+            self.assertTrue(n)
+
+    def test_in_function(self):
+        self.try_with("def foo():\n\tbar.baz()\n\tstart=3")
+
+class Test_find_binding(support.TestCase):
+    def find_binding(self, name, string, package=None):
+        return fixer_util.find_binding(name, parse(string), package)
+
+    def test_simple_assignment(self):
+        self.assertTrue(self.find_binding("a", "a = b"))
+        self.assertTrue(self.find_binding("a", "a = [b, c, d]"))
+        self.assertTrue(self.find_binding("a", "a = foo()"))
+        self.assertTrue(self.find_binding("a", "a = foo().foo.foo[6][foo]"))
+        self.assertFalse(self.find_binding("a", "foo = a"))
+        self.assertFalse(self.find_binding("a", "foo = (a, b, c)"))
+
+    def test_tuple_assignment(self):
+        self.assertTrue(self.find_binding("a", "(a,) = b"))
+        self.assertTrue(self.find_binding("a", "(a, b, c) = [b, c, d]"))
+        self.assertTrue(self.find_binding("a", "(c, (d, a), b) = foo()"))
+        self.assertTrue(self.find_binding("a", "(a, b) = foo().foo[6][foo]"))
+        self.assertFalse(self.find_binding("a", "(foo, b) = (b, a)"))
+        self.assertFalse(self.find_binding("a", "(foo, (b, c)) = (a, b, c)"))
+
+    def test_list_assignment(self):
+        self.assertTrue(self.find_binding("a", "[a] = b"))
+        self.assertTrue(self.find_binding("a", "[a, b, c] = [b, c, d]"))
+        self.assertTrue(self.find_binding("a", "[c, [d, a], b] = foo()"))
+        self.assertTrue(self.find_binding("a", "[a, b] = foo().foo[a][foo]"))
+        self.assertFalse(self.find_binding("a", "[foo, b] = (b, a)"))
+        self.assertFalse(self.find_binding("a", "[foo, [b, c]] = (a, b, c)"))
+
+    def test_invalid_assignments(self):
+        self.assertFalse(self.find_binding("a", "foo.a = 5"))
+        self.assertFalse(self.find_binding("a", "foo[a] = 5"))
+        self.assertFalse(self.find_binding("a", "foo(a) = 5"))
+        self.assertFalse(self.find_binding("a", "foo(a, b) = 5"))
+
+    def test_simple_import(self):
+        self.assertTrue(self.find_binding("a", "import a"))
+        self.assertTrue(self.find_binding("a", "import b, c, a, d"))
+        self.assertFalse(self.find_binding("a", "import b"))
+        self.assertFalse(self.find_binding("a", "import b, c, d"))
+
+    def test_from_import(self):
+        self.assertTrue(self.find_binding("a", "from x import a"))
+        self.assertTrue(self.find_binding("a", "from a import a"))
+        self.assertTrue(self.find_binding("a", "from x import b, c, a, d"))
+        self.assertTrue(self.find_binding("a", "from x.b import a"))
+        self.assertTrue(self.find_binding("a", "from x.b import b, c, a, d"))
+        self.assertFalse(self.find_binding("a", "from a import b"))
+        self.assertFalse(self.find_binding("a", "from a.d import b"))
+        self.assertFalse(self.find_binding("a", "from d.a import b"))
+
+    def test_import_as(self):
+        self.assertTrue(self.find_binding("a", "import b as a"))
+        self.assertTrue(self.find_binding("a", "import b as a, c, a as f, d"))
+        self.assertFalse(self.find_binding("a", "import a as f"))
+        self.assertFalse(self.find_binding("a", "import b, c as f, d as e"))
+
+    def test_from_import_as(self):
+        self.assertTrue(self.find_binding("a", "from x import b as a"))
+        self.assertTrue(self.find_binding("a", "from x import g as a, d as b"))
+        self.assertTrue(self.find_binding("a", "from x.b import t as a"))
+        self.assertTrue(self.find_binding("a", "from x.b import g as a, d"))
+        self.assertFalse(self.find_binding("a", "from a import b as t"))
+        self.assertFalse(self.find_binding("a", "from a.d import b as t"))
+        self.assertFalse(self.find_binding("a", "from d.a import b as t"))
+
+    def test_simple_import_with_package(self):
+        self.assertTrue(self.find_binding("b", "import b"))
+        self.assertTrue(self.find_binding("b", "import b, c, d"))
+        self.assertFalse(self.find_binding("b", "import b", "b"))
+        self.assertFalse(self.find_binding("b", "import b, c, d", "c"))
+
+    def test_from_import_with_package(self):
+        self.assertTrue(self.find_binding("a", "from x import a", "x"))
+        self.assertTrue(self.find_binding("a", "from a import a", "a"))
+        self.assertTrue(self.find_binding("a", "from x import *", "x"))
+        self.assertTrue(self.find_binding("a", "from x import b, c, a, d", "x"))
+        self.assertTrue(self.find_binding("a", "from x.b import a", "x.b"))
+        self.assertTrue(self.find_binding("a", "from x.b import *", "x.b"))
+        self.assertTrue(self.find_binding("a", "from x.b import b, c, a, d", "x.b"))
+        self.assertFalse(self.find_binding("a", "from a import b", "a"))
+        self.assertFalse(self.find_binding("a", "from a.d import b", "a.d"))
+        self.assertFalse(self.find_binding("a", "from d.a import b", "a.d"))
+        self.assertFalse(self.find_binding("a", "from x.y import *", "a.b"))
+
+    def test_import_as_with_package(self):
+        self.assertFalse(self.find_binding("a", "import b.c as a", "b.c"))
+        self.assertFalse(self.find_binding("a", "import a as f", "f"))
+        self.assertFalse(self.find_binding("a", "import a as f", "a"))
+
+    def test_from_import_as_with_package(self):
+        # Because it would take a lot of special-case code in the fixers
+        # to deal with from foo import bar as baz, we'll simply always
+        # fail if there is an "from ... import ... as ..."
+        self.assertFalse(self.find_binding("a", "from x import b as a", "x"))
+        self.assertFalse(self.find_binding("a", "from x import g as a, d as b", "x"))
+        self.assertFalse(self.find_binding("a", "from x.b import t as a", "x.b"))
+        self.assertFalse(self.find_binding("a", "from x.b import g as a, d", "x.b"))
+        self.assertFalse(self.find_binding("a", "from a import b as t", "a"))
+        self.assertFalse(self.find_binding("a", "from a import b as t", "b"))
+        self.assertFalse(self.find_binding("a", "from a import b as t", "t"))
+
+    def test_function_def(self):
+        self.assertTrue(self.find_binding("a", "def a(): pass"))
+        self.assertTrue(self.find_binding("a", "def a(b, c, d): pass"))
+        self.assertTrue(self.find_binding("a", "def a(): b = 7"))
+        self.assertFalse(self.find_binding("a", "def d(b, (c, a), e): pass"))
+        self.assertFalse(self.find_binding("a", "def d(a=7): pass"))
+        self.assertFalse(self.find_binding("a", "def d(a): pass"))
+        self.assertFalse(self.find_binding("a", "def d(): a = 7"))
+
+        s = """
+            def d():
+                def a():
+                    pass"""
+        self.assertFalse(self.find_binding("a", s))
+
+    def test_class_def(self):
+        self.assertTrue(self.find_binding("a", "class a: pass"))
+        self.assertTrue(self.find_binding("a", "class a(): pass"))
+        self.assertTrue(self.find_binding("a", "class a(b): pass"))
+        self.assertTrue(self.find_binding("a", "class a(b, c=8): pass"))
+        self.assertFalse(self.find_binding("a", "class d: pass"))
+        self.assertFalse(self.find_binding("a", "class d(a): pass"))
+        self.assertFalse(self.find_binding("a", "class d(b, a=7): pass"))
+        self.assertFalse(self.find_binding("a", "class d(b, *a): pass"))
+        self.assertFalse(self.find_binding("a", "class d(b, **a): pass"))
+        self.assertFalse(self.find_binding("a", "class d: a = 7"))
+
+        s = """
+            class d():
+                class a():
+                    pass"""
+        self.assertFalse(self.find_binding("a", s))
+
+    def test_for(self):
+        self.assertTrue(self.find_binding("a", "for a in r: pass"))
+        self.assertTrue(self.find_binding("a", "for a, b in r: pass"))
+        self.assertTrue(self.find_binding("a", "for (a, b) in r: pass"))
+        self.assertTrue(self.find_binding("a", "for c, (a,) in r: pass"))
+        self.assertTrue(self.find_binding("a", "for c, (a, b) in r: pass"))
+        self.assertTrue(self.find_binding("a", "for c in r: a = c"))
+        self.assertFalse(self.find_binding("a", "for c in a: pass"))
+
+    def test_for_nested(self):
+        s = """
+            for b in r:
+                for a in b:
+                    pass"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            for b in r:
+                for a, c in b:
+                    pass"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            for b in r:
+                for (a, c) in b:
+                    pass"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            for b in r:
+                for (a,) in b:
+                    pass"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            for b in r:
+                for c, (a, d) in b:
+                    pass"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            for b in r:
+                for c in b:
+                    a = 7"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            for b in r:
+                for c in b:
+                    d = a"""
+        self.assertFalse(self.find_binding("a", s))
+
+        s = """
+            for b in r:
+                for c in a:
+                    d = 7"""
+        self.assertFalse(self.find_binding("a", s))
+
+    def test_if(self):
+        self.assertTrue(self.find_binding("a", "if b in r: a = c"))
+        self.assertFalse(self.find_binding("a", "if a in r: d = e"))
+
+    def test_if_nested(self):
+        s = """
+            if b in r:
+                if c in d:
+                    a = c"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            if b in r:
+                if c in d:
+                    c = a"""
+        self.assertFalse(self.find_binding("a", s))
+
+    def test_while(self):
+        self.assertTrue(self.find_binding("a", "while b in r: a = c"))
+        self.assertFalse(self.find_binding("a", "while a in r: d = e"))
+
+    def test_while_nested(self):
+        s = """
+            while b in r:
+                while c in d:
+                    a = c"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            while b in r:
+                while c in d:
+                    c = a"""
+        self.assertFalse(self.find_binding("a", s))
+
+    def test_try_except(self):
+        s = """
+            try:
+                a = 6
+            except:
+                b = 8"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            except:
+                a = 6"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            except KeyError:
+                pass
+            except:
+                a = 6"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            except:
+                b = 6"""
+        self.assertFalse(self.find_binding("a", s))
+
+    def test_try_except_nested(self):
+        s = """
+            try:
+                try:
+                    a = 6
+                except:
+                    pass
+            except:
+                b = 8"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            except:
+                try:
+                    a = 6
+                except:
+                    pass"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            except:
+                try:
+                    pass
+                except:
+                    a = 6"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                try:
+                    b = 8
+                except KeyError:
+                    pass
+                except:
+                    a = 6
+            except:
+                pass"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                pass
+            except:
+                try:
+                    b = 8
+                except KeyError:
+                    pass
+                except:
+                    a = 6"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            except:
+                b = 6"""
+        self.assertFalse(self.find_binding("a", s))
+
+        s = """
+            try:
+                try:
+                    b = 8
+                except:
+                    c = d
+            except:
+                try:
+                    b = 6
+                except:
+                    t = 8
+                except:
+                    o = y"""
+        self.assertFalse(self.find_binding("a", s))
+
+    def test_try_except_finally(self):
+        s = """
+            try:
+                c = 6
+            except:
+                b = 8
+            finally:
+                a = 9"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            finally:
+                a = 6"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            finally:
+                b = 6"""
+        self.assertFalse(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            except:
+                b = 9
+            finally:
+                b = 6"""
+        self.assertFalse(self.find_binding("a", s))
+
+    def test_try_except_finally_nested(self):
+        s = """
+            try:
+                c = 6
+            except:
+                b = 8
+            finally:
+                try:
+                    a = 9
+                except:
+                    b = 9
+                finally:
+                    c = 9"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            finally:
+                try:
+                    pass
+                finally:
+                    a = 6"""
+        self.assertTrue(self.find_binding("a", s))
+
+        s = """
+            try:
+                b = 8
+            finally:
+                try:
+                    b = 6
+                finally:
+                    b = 7"""
+        self.assertFalse(self.find_binding("a", s))
+
+class Test_touch_import(support.TestCase):
+
+    def test_after_docstring(self):
+        node = parse('"""foo"""\nbar()')
+        fixer_util.touch_import(None, "foo", node)
+        self.assertEqual(str(node), '"""foo"""\nimport foo\nbar()\n\n')
+
+    def test_after_imports(self):
+        node = parse('"""foo"""\nimport bar\nbar()')
+        fixer_util.touch_import(None, "foo", node)
+        self.assertEqual(str(node), '"""foo"""\nimport bar\nimport foo\nbar()\n\n')
+
+    def test_beginning(self):
+        node = parse('bar()')
+        fixer_util.touch_import(None, "foo", node)
+        self.assertEqual(str(node), 'import foo\nbar()\n\n')
+
+    def test_from_import(self):
+        node = parse('bar()')
+        fixer_util.touch_import("html", "escape", node)
+        self.assertEqual(str(node), 'from html import escape\nbar()\n\n')
+
+    def test_name_import(self):
+        node = parse('bar()')
+        fixer_util.touch_import(None, "cgi", node)
+        self.assertEqual(str(node), 'import cgi\nbar()\n\n')
+
+class Test_find_indentation(support.TestCase):
+
+    def test_nothing(self):
+        fi = fixer_util.find_indentation
+        node = parse("node()")
+        self.assertEqual(fi(node), "")
+        node = parse("")
+        self.assertEqual(fi(node), "")
+
+    def test_simple(self):
+        fi = fixer_util.find_indentation
+        node = parse("def f():\n    x()")
+        self.assertEqual(fi(node), "")
+        self.assertEqual(fi(node.children[0].children[4].children[2]), "    ")
+        node = parse("def f():\n    x()\n    y()")
+        self.assertEqual(fi(node.children[0].children[4].children[4]), "    ")
diff --git a/lib3/2to3/scripts/benchmark.py b/lib3/2to3/scripts/benchmark.py
new file mode 100644
--- /dev/null
+++ b/lib3/2to3/scripts/benchmark.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python2.5
+"""
+This is a benchmarking script to test the speed of 2to3's pattern matching
+system. It's equivalent to "refactor.py -f all" for every Python module
+in sys.modules, but without engaging the actual transformations.
+"""
+
+__author__ = "Collin Winter <collinw at gmail.com>"
+
+# Python imports
+import os.path
+import sys
+from time import time
+
+# Test imports
+from .support import adjust_path
+adjust_path()
+
+# Local imports
+from .. import refactor
+
+### Mock code for refactor.py and the fixers
+###############################################################################
+class Options:
+    def __init__(self, **kwargs):
+        for k, v in list(kwargs.items()):
+            setattr(self, k, v)
+
+        self.verbose = False
+
+def dummy_transform(*args, **kwargs):
+    pass
+
+### Collect list of modules to match against
+###############################################################################
+files = []
+for mod in list(sys.modules.values()):
+    if mod is None or not hasattr(mod, '__file__'):
+        continue
+    f = mod.__file__
+    if f.endswith('.pyc'):
+        f = f[:-1]
+    if f.endswith('.py'):
+        files.append(f)
+
+### Set up refactor and run the benchmark
+###############################################################################
+options = Options(fix=["all"], print_function=False, doctests_only=False)
+refactor = refactor.RefactoringTool(options)
+for fixer in refactor.fixers:
+    # We don't want them to actually fix the tree, just match against it.
+    fixer.transform = dummy_transform
+
+t = time()
+for f in files:
+    print("Matching", f)
+    refactor.refactor_file(f)
+print("%d seconds to match %d files" % (time() - t, len(sys.modules)))
diff --git a/lib3/2to3/scripts/find_pattern.py b/lib3/2to3/scripts/find_pattern.py
new file mode 100755
--- /dev/null
+++ b/lib3/2to3/scripts/find_pattern.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+
+"""Script that makes determining PATTERN for a new fix much easier.
+
+Figuring out exactly what PATTERN I want for a given fixer class is
+getting tedious. This script will step through each possible subtree
+for a given string, allowing you to select which one you want. It will
+then try to figure out an appropriate pattern to match that tree. This
+pattern will require some editing (it will be overly restrictive) but
+should provide a solid base to work with and handle the tricky parts.
+
+Usage:
+
+    python find_pattern.py "g.throw(E, V, T)"
+
+This will step through each subtree in the parse. To reject a
+candidate subtree, hit enter; to accept a candidate, hit "y" and
+enter. The pattern will be spit out to stdout.
+
+For example, the above will yield a succession of possible snippets,
+skipping all leaf-only trees. I accept
+
+'g.throw(E, V, T)'
+
+This causes find_pattern to spit out
+
+power< 'g' trailer< '.' 'throw' >
+           trailer< '(' arglist< 'E' ',' 'V' ',' 'T' > ')' > >
+
+
+Some minor tweaks later, I'm left with
+
+power< any trailer< '.' 'throw' >
+       trailer< '(' args=arglist< exc=any ',' val=any [',' tb=any] > ')' > >
+
+which is exactly what I was after.
+
+Larger snippets can be placed in a file (as opposed to a command-line
+arg) and processed with the -f option.
+"""
+
+__author__ = "Collin Winter <collinw at gmail.com>"
+
+# Python imports
+import optparse
+import sys
+from io import StringIO
+
+# Local imports
+from lib2to3 import pytree
+from lib2to3.pgen2 import driver
+from lib2to3.pygram import python_symbols, python_grammar
+
+driver = driver.Driver(python_grammar, convert=pytree.convert)
+
+def main(args):
+    parser = optparse.OptionParser(usage="find_pattern.py [options] [string]")
+    parser.add_option("-f", "--file", action="store",
+                      help="Read a code snippet from the specified file")
+
+    # Parse command line arguments
+    options, args = parser.parse_args(args)
+    if options.file:
+        tree = driver.parse_file(options.file)
+    elif len(args) > 1:
+        tree = driver.parse_stream(StringIO(args[1] + "\n"))
+    else:
+        print("You must specify an input file or an input string", file=sys.stderr)
+        return 1
+
+    examine_tree(tree)
+    return 0
+
+def examine_tree(tree):
+    for node in tree.post_order():
+        if isinstance(node, pytree.Leaf):
+            continue
+        print(repr(str(node)))
+        verdict = input()
+        if verdict.strip():
+            print(find_pattern(node))
+            return
+
+def find_pattern(node):
+    if isinstance(node, pytree.Leaf):
+        return repr(node.value)
+
+    return find_symbol(node.type) + \
+           "< " + " ".join(find_pattern(n) for n in node.children) + " >"
+
+def find_symbol(sym):
+    for n, v in list(python_symbols.__dict__.items()):
+        if v == sym:
+            return n
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))
diff --git a/lib3/2to3/test.py b/lib3/2to3/test.py
new file mode 100755
--- /dev/null
+++ b/lib3/2to3/test.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+
+"""Main test file for 2to3.
+
+Running "python test.py" will run all tests in tests/test_*.py.
+"""
+# Author: Collin Winter
+
+import unittest
+from lib2to3 import tests
+import lib2to3.tests.support
+from sys import exit, argv
+
+if "-h" in argv or "--help" in argv or len(argv) > 2:
+    print("Usage: %s [-h] [test suite[.test class]]" %(argv[0]))
+    print("default   : run all tests in lib2to3/tests/test_*.py")
+    print("test suite: run tests in lib2to3/tests/<test suite>")
+    print("test class : run tests in <test suite>.<test class>")
+    exit(1)
+
+if len(argv) == 2:
+    mod = tests
+    for m in argv[1].split("."):
+        mod = getattr(mod, m, None)
+        if not mod:
+            print("Error importing %s" %(m))
+            exit(1)
+
+    if argv[1].find(".") == -1:
+        # Just the module was specified, load all the tests
+        suite = unittest.TestLoader().loadTestsFromModule(mod)
+    else:
+        # A class was specified, load that
+        suite = unittest.makeSuite(mod)
+else:
+    suite = tests.all_tests
+
+try:
+    tests.support.run_all_tests(tests=suite)
+except KeyboardInterrupt:
+    pass
diff --git a/lib3/Chameleon-2.9.2/.gitignore b/lib3/Chameleon-2.9.2/.gitignore
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/.gitignore
@@ -0,0 +1,12 @@
+*.pyc
+*.egg
+*.egg-info
+.coverage
+.tox/
+coverage.xml
+nosetests.xml
+*.tar.gz
+env25/
+env26/
+env27/
+env32/
diff --git a/lib3/Chameleon-2.9.2/CHANGES.rst b/lib3/Chameleon-2.9.2/CHANGES.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/CHANGES.rst
@@ -0,0 +1,1075 @@
+Changes
+=======
+
+2.9.2 (2012-06-06)
+------------------
+
+Bugfixes:
+
+- Fixed a PyPy incompatibility.
+
+- Fixed issue #109 which caused testing failures on some platforms.
+
+2.9.1 (2012-06-01)
+------------------
+
+Bugfixes:
+
+- Fixed issue #103. The ``tal:on-error`` statement now always adds an
+  explicit end-tag to the element, even with a substitution content of
+  nothing.
+
+- Fixed issue #113. The ``tal:on-error`` statement now works correctly
+  also for dynamic attributes. That is, the fallback tag now includes
+  only static attributes.
+
+- Fixed name error which prevented the benchmark from running
+  correctly.
+
+Compatibility:
+
+- Fixed deprecation warning on Python 3 for zope interface implements
+  declaration. This fixes issue #116.
+
+2.9.0 (2012-05-31)
+------------------
+
+Features:
+
+- The translation function now gets the ``econtext`` argument as the
+  value for ``context``. Note that historically, this was usually an
+  HTTP request which might provide language negotiation data through a
+  dictionary interface.
+  [alvinyue]
+
+Bugfixes:
+
+- Fixed import alias issue which would lead to a syntax error in
+  generated Python code. Fixes issue #114.
+
+2.8.5 (2012-05-02)
+------------------
+
+Bugfixes:
+
+- Fixed minor installation issues on Python 2.5 and 3.
+  [ppaez]
+
+- Ensure output is unicode even when trivial (an empty string).
+
+2.8.4 (2012-04-18)
+------------------
+
+Features:
+
+- In exception output, long filenames are now truncated to 60
+  characters of output, preventing line wrap which makes it difficult
+  to scan the exception output.
+
+Bugfixes:
+
+- Include filename and location in exception output for exceptions
+  raised during compilation.
+
+- If a trivial translation substitution variable is given (i.e. an
+  empty string), simply ignore it. This fixes issue #106.
+
+2.8.3 (2012-04-16)
+------------------
+
+Features:
+
+- Log template source on debug-level before cooking.
+
+- The `target_language` argument, if given, is now available as a
+  variable in templates.
+
+2.8.2 (2012-03-30)
+------------------
+
+Features:
+
+- Temporary caches used in debug mode are cleaned up eagerly, rather
+  than waiting for process termination.
+  [mitchellrj]
+
+Bugfixes:
+
+- The `index`, `start` and `end` methods on the TAL repeat object are
+  now callable. This fixes an incompatibility with ZPT.
+
+- The loader now correctly handles absolute paths on Windows.
+  [rdale]
+
+2.8.1 (2012-03-29)
+------------------
+
+Features:
+
+- The exception formatter now lists errors in 'wrapping order'. This
+  means that the innermost, and presumably most relevant exception is
+  shown last.
+
+Bugfixes:
+
+- The exception formatter now correctly recognizes nested errors and
+  does not rewrap the dynamically generated exception class.
+
+- The exception formatter now correctly sets the ``__module__``
+  attribute to that of the original exception class.
+
+2.8.0 (2012-02-29)
+------------------
+
+Features:
+
+- Added support for code blocks using the `<?python ... ?>` processing
+  instruction syntax.
+
+  The scope is name assignments is up until the nearest macro
+  definition, or the template itself if macros are not used.
+
+Bugfixes:
+
+- Fall back to the exception class' ``__new__`` method to safely
+  create an exception object that is not implemented in Python.
+
+- The exception formatter now keeps track of already formatted
+  exceptions, and ignores them from further output.
+
+2.7.4 (2012-02-27)
+------------------
+
+- The error handler now invokes the ``__init__`` method of
+  ``BaseException`` instead of the possibly overriden method (which
+  may take required arguments). This fixes issue #97.
+  [j23d, malthe]
+
+2.7.3 (2012-01-16)
+------------------
+
+Bugfixes:
+
+- The trim whitespace option now correctly trims actual whitespace to
+  a single character, appearing either to the left or to the right of
+  an element prefix or suffix string.
+
+2.7.2 (2012-01-08)
+------------------
+
+Features:
+
+- Added option ``trim_attribute_space`` that decides whether attribute
+  whitespace is stripped (at most down to a single space). This option
+  exists to provide compatibility with the reference
+  implementation. Fixes issue #85.
+
+Bugfixes:
+
+- Ignore unhashable builtins when generating a reverse builtin
+  map to quickly look up a builtin value.
+  [malthe]
+
+- Apply translation mapping even when a translation function is not
+  available. This fixes issue #83.
+  [malthe]
+
+- Fixed issue #80. The translation domain for a slot is defined by the
+  source document, i.e. the template providing the content for a slot
+  whether it be the default or provided through ``metal:fill-slot``.
+  [jcbrand]
+
+- In certain circumstances, a Unicode non-breaking space character would cause
+  a define clause to fail to parse.
+
+2.7.1 (2011-12-29)
+------------------
+
+Features:
+
+- Enable expression interpolation in CDATA.
+
+- The page template class now implements dictionary access to macros::
+
+     template[name]
+
+  This is a short-hand for::
+
+     template.macros[name]
+
+Bugfixes:
+
+- An invalid define clause would be silently ignored; we now raise a
+  language error exception. This fixes issue #79.
+
+- Fixed regression where ``${...}`` interpolation expressions could
+  not span multiple lines. This fixes issue #77.
+
+2.7.0 (2011-12-13)
+------------------
+
+Features:
+
+- The ``load:`` expression now derives from the string expression such
+  that the ``${...}`` operator can be used for expression
+  interpolation.
+
+- The ``load:`` expression now accepts asset specs; these are resolved
+  by the ``pkg_resources.resource_filename`` function::
+
+    <package_name>:<path>
+
+  An example from the test suite::
+
+    chameleon:tests/inputs/hello_world.pt
+
+Bugfixes:
+
+- If an attribute name for translation was not a valid Python
+  identifier, the compiler would generate invalid code. This has been
+  fixed, and the compiler now also throws an exception if an attribute
+  specification contains a comma. (Note that the only valid separator
+  character is the semicolon, when specifying attributes for
+  translation via the ``i18n:translate`` statement). This addresses
+  issue #76.
+
+2.6.2 (2011-12-08)
+------------------
+
+Bugfixes:
+
+- Fixed issue where ``tal:on-error`` would not respect
+  ``tal:omit-tag`` or namespace elements which are omitted by default
+  (such as ``<tal:block />``).
+
+- Fixed issue where ``macros`` attribute would not be available on
+  file-based templates due to incorrect initialization.
+
+- The ``TryExcept`` and ``TryFinally`` AST nodes are not available on
+  Python 3.3. These have been aliased to ``Try``. This fixes issue
+  #75.
+
+Features:
+
+- The TAL repeat item now makes a security declaration that grants
+  access to unprotected subobjects on the Zope 2 platform::
+
+    __allow_access_to_unprotected_subobjects__ = True
+
+  This is required for legacy compatibility and does not affect other
+  environments.
+
+- The template object now has a method ``write(body)`` which
+  explicitly decodes and cooks a string input.
+
+- Added configuration option ``loader_class`` which sets the class
+  used to create the template loader object.
+
+  The class (essentially a callable) is created at template
+  construction time.
+
+2.6.1 (2011-11-30)
+------------------
+
+Bugfixes:
+
+- Decode HTML entities in expression interpolation strings. This fixes
+  issue #74.
+
+- Allow ``xml`` and ``xmlns`` attributes on TAL, I18N and METAL
+  namespace elements. This fixes issue #73.
+
+2.6.0 (2011-11-24)
+------------------
+
+Features:
+
+- Added support for implicit translation:
+
+  The ``implicit_i18n_translate`` option enables implicit translation
+  of text. The ``implicit_i18n_attributes`` enables implicit
+  translation of attributes. The latter must be a set and for an
+  attribute to be implicitly translated, its lowercase string value
+  must be included in the set.
+
+- Added option ``strict`` (enabled by default) which decides whether
+  expressions are required to be valid at compile time. That is, if
+  not set, an exception is only raised for an invalid expression at
+  evaluation time.
+
+- An expression error now results in an exception only if the
+  expression is attempted evaluated during a rendering.
+
+- Added a configuration option ``prepend_relative_search_path`` which
+  decides whether the path relative to a file-based template is
+  prepended to the load search path. The default is ``True``.
+
+- Added a configuration option ``search_path`` to the file-based
+  template class, which adds additional paths to the template load
+  instance bound to the ``load:`` expression. The option takes a
+  string path or an iterable yielding string paths. The default value
+  is the empty set.
+
+Bugfixes:
+
+- Exception instances now support pickle/unpickle.
+
+- An attributes in i18n:attributes no longer needs to match an
+  existing or dynamic attribute in order to appear in the
+  element. This fixes issue #66.
+
+2.5.3 (2011-10-23)
+------------------
+
+Bugfixes:
+
+- Fixed an issue where a nested macro slot definition would fail even
+  though there existed a parent macro definition. This fixes issue
+  #69.
+
+2.5.2 (2011-10-12)
+------------------
+
+Bugfixes:
+
+- Fixed an issue where technically invalid input would result in a
+  compiler error.
+
+Features:
+
+- The markup class now inherits from the unicode string type such that
+  it's compatible with the string interface.
+
+2.5.1 (2011-09-29)
+------------------
+
+Bugfixes:
+
+- The symbol names "convert", "decode" and "translate" are now no
+  longer set as read-only *compiler internals*. This fixes issue #65.
+
+- Fixed an issue where a macro extension chain nested two levels (a
+  template uses a macro that extends a macro) would lose the middle
+  slot definitions if slots were defined nested.
+
+  The compiler now throws an error if a nested slot definition is used
+  outside a macro extension context.
+
+2.5.0 (2011-09-23)
+------------------
+
+Features:
+
+- An expression type ``structure:`` is now available which wraps the
+  expression result as *structure* such that it is not escaped on
+  insertion, e.g.::
+
+    <div id="content">
+       ${structure: context.body}
+    </div>
+
+  This also means that the ``structure`` keyword for ``tal:content``
+  and ``tal:replace`` now has an alternative spelling via the
+  expression type ``structure:``.
+
+- The string-based template constructor now accepts encoded input.
+
+2.4.6 (2011-09-23)
+------------------
+
+Bugfixes:
+
+- The ``tal:on-error`` statement should catch all exceptions.
+
+- Fixed issue that would prevent escaping of interpolation expression
+  values appearing in text.
+
+2.4.5 (2011-09-21)
+------------------
+
+Bugfixes:
+
+- The ``tal:on-error`` handler should have a ``error`` variable
+  defined that has the value of the exception thrown.
+
+- The ``tal:on-error`` statement is a substitution statement and
+  should support the "text" and "structure" insertion methods.
+
+2.4.4 (2011-09-15)
+------------------
+
+Bugfixes:
+
+- An encoding specified in the XML document preamble is now read and
+  used to decode the template input to unicode. This fixes issue #55.
+
+- Encoded expression input on Python 3 is now correctly
+  decoded. Previously, the string representation output would be
+  included instead of an actually decoded string.
+
+- Expression result conversion steps are now correctly included in
+  error handling such that the exception output points to the
+  expression location.
+
+2.4.3 (2011-09-13)
+------------------
+
+Features:
+
+- When an encoding is provided, pass the 'ignore' flag to avoid
+  decoding issues with bad input.
+
+Bugfixes:
+
+- Fixed pypy compatibility issue (introduced in previous release).
+
+2.4.2 (2011-09-13)
+------------------
+
+Bugfixes:
+
+- Fixed an issue in the compiler where an internal variable (such as a
+  translation default value) would be cached, resulting in variable
+  scope corruption (see issue #49).
+
+2.4.1 (2011-09-08)
+------------------
+
+Bugfixes:
+
+- Fixed an issue where a default value for an attribute would
+  sometimes spill over into another attribute.
+
+- Fixed issue where the use of the ``default`` name in an attribute
+  interpolation expression would print the attribute value. This is
+  unexpected, because it's an expression, not a static text suitable
+  for output. An attribute value of ``default`` now correctly drops
+  the attribute.
+
+2.4.0 (2011-08-22)
+------------------
+
+Features:
+
+- Added an option ``boolean_attributes`` to evaluate and render a
+  provided set of attributes using a boolean logic: if the attribute
+  is a true value, the value will be the attribute name, otherwise the
+  attribute is dropped.
+
+  In the reference implementation, the following attributes are
+  configured as boolean values when the template is rendered in
+  HTML-mode::
+
+      "compact", "nowrap", "ismap", "declare", "noshade",
+      "checked", "disabled", "readonly", "multiple", "selected",
+      "noresize", "defer"
+
+  Note that in Chameleon, these attributes must be manually provided.
+
+Bugfixes:
+
+- The carriage return character (used on Windows platforms) would
+  incorrectly be included in Python comments.
+
+  It is now replaced with a line break.
+
+  This fixes issue #44.
+
+2.3.8 (2011-08-19)
+------------------
+
+- Fixed import error that affected Python 2.5 only.
+
+2.3.7 (2011-08-19)
+------------------
+
+Features:
+
+- Added an option ``literal_false`` that disables the default behavior
+  of dropping an attribute for a value of ``False`` (in addition to
+  ``None``). This modified behavior is the behavior exhibited in
+  reference implementation.
+
+Bugfixes:
+
+- Undo attribute special HTML attribute behavior (see previous
+  release).
+
+  This turned out not to be a compatible behavior; rather, boolean
+  values should simply be coerced to a string.
+
+  Meanwhile, the reference implementation does support an HTML mode in
+  which the special attribute behavior is exhibited.
+
+  We do not currently support this mode.
+
+2.3.6 (2011-08-18)
+------------------
+
+Features:
+
+- Certain HTML attribute names now have a special behavior for a
+  attribute value of ``True`` (or ``default`` if no default is
+  defined). For these attributes, this return value will result in the
+  name being printed as the value::
+
+    <input type="input" tal:attributes="checked True" />
+
+  will be rendered as::
+
+    <input type="input" checked="checked" />
+
+  This behavior is compatible with the reference implementation.
+
+2.3.5 (2011-08-18)
+------------------
+
+Features:
+
+- Added support for the set operator (``{item, item, ...}``).
+
+Bugfixes:
+
+- If macro is defined on the same element as a translation name, this
+  no longer results in a "translation name not allowed outside
+  translation" error. This fixes issue #43.
+
+- Attribute fallback to dictionary lookup now works on multiple items
+  (e.g. ``d1.d2.d2``). This fixes issue #42.
+
+2.3.4 (2011-08-16)
+------------------
+
+Features:
+
+- When inserting content in either attributes or text, a value of
+  ``True`` (like ``False`` and ``None``) will result in no
+  action.
+
+- Use statically assigned variables for ``"attrs"`` and
+  ``"default"``. This change yields a performance improvement of
+  15-20%.
+
+- The template loader class now accepts an optional argument
+  ``default_extension`` which accepts a filename extension which will
+  be appended to the filename if there's not already an extension.
+
+Bugfixes:
+
+- The default symbol is now ``True`` for an attribute if the attribute
+  default is not provided. Note that the result is that the attribute
+  is dropped. This fixes issue #41.
+
+- Fixed an issue where assignment to a variable ``"type"`` would
+  fail. This fixes issue #40.
+
+- Fixed an issue where an (unsuccesful) assignment for a repeat loop
+  to a compiler internal name would not result in an error.
+
+- If the translation function returns the identical object, manually
+  coerce it to string. This fixes a compatibility issue with
+  translation functions which do not convert non-string objects to a
+  string value, but simply return them unchanged.
+
+2.3.3 (2011-08-15)
+------------------
+
+Features:
+
+- The ``load:`` expression now passes the initial keyword arguments to
+  its template loader (e.g. ``auto_reload`` and ``encoding``).
+
+- In the exception output, string variable values are now limited to a
+  limited output of characters, single line only.
+
+Bugfixes:
+
+- Fixed horizontal alignment of exception location info
+  (i.e. 'String:', 'Filename:' and 'Location:') such that they match
+  the template exception formatter.
+
+2.3.2 (2011-08-11)
+------------------
+
+Bugfixes:
+
+- Fixed issue where i18n:domain would not be inherited through macros
+  and slots. This fixes issue #37.
+
+2.3.1 (2011-08-11)
+------------------
+
+Features:
+
+- The ``Builtin`` node type may now be used to represent any Python
+  local or global name. This allows expression compilers to refer to
+  e.g. ``get`` or ``getitem``, or to explicit require a builtin object
+  such as one from the ``extra_builtins`` dictionary.
+
+Bugfixes:
+
+- Builtins which are not explicitly disallowed may now be redefined
+  and used as variables (e.g. ``nothing``).
+
+- Fixed compiler issue with circular node annotation loop.
+
+2.3 (2011-08-10)
+----------------
+
+Features:
+
+- Added support for the following syntax to disable inline evaluation
+  in a comment:
+
+    <!--? comment appears verbatim (no ${...} evaluation) -->
+
+  Note that the initial question mark character (?) will be omitted
+  from output.
+
+- The parser now accepts '<' and '>' in attributes. Note that this is
+  invalid markup. Previously, the '<' would not be accepted as a valid
+  attribute value, but this would result in an 'unexpected end tag'
+  error elsewhere. This fixes issue #38.
+
+- The expression compiler now provides methods ``assign_text`` and
+  ``assign_value`` such that a template engine might configure this
+  value conversion to support e.g. encoded strings.
+
+  Note that currently, the only client for the ``assign_text`` method
+  is the string expression type.
+
+- Enable template loader for string-based template classes. Note that
+  the ``filename`` keyword argument may be provided on initialization
+  to identify the template source by filename. This fixes issue #36.
+
+- Added ``extra_builtins`` option to the page template class. These
+  builtins are added to the default builtins dictionary at cook time
+  and may be provided at initialization using the ``extra_builtins``
+  keyword argument.
+
+Bugfixes:
+
+- If a translation domain is set for a fill slot, use this setting
+  instead of the macro template domain.
+
+- The Python expression compiler now correctly decodes HTML entities
+  ``'gt'`` and ``'lt'``. This fixes issue #32.
+
+- The string expression compiler now correctly handles encoded text
+  (when support for encoded strings is enabled). This fixes issue #35.
+
+- Fixed an issue where setting the ``filename`` attribute on a
+  file-based template would not automatically cause an invalidation.
+
+- Exceptions raised by Chameleon can now be copied via
+  ``copy.copy``. This fixes issue #36.
+  [leorochael]
+
+- If copying the exception fails in the exception handler, simply
+  re-raise the original exception and log a warning.
+
+2.2 (2011-07-28)
+----------------
+
+Features:
+
+- Added new expression type ``load:`` that allows loading a
+  template. Both relative and absolute paths are supported. If the
+  path given is relative, then it will be resolved with respect to the
+  directory of the template.
+
+- Added support for dynamic evaluation of expressions.
+
+  Note that this is to support legacy applications. It is not
+  currently wired into the provided template classes.
+
+- Template classes now have a ``builtins`` attribute which may be used
+  to define built-in variables always available in the template
+  variable scope.
+
+Incompatibilities:
+
+- The file-based template class no longer accepts a parameter
+  ``loader``. This parameter would be used to load a template from a
+  relative path, using a ``find(filename)`` method. This was however,
+  undocumented, and probably not very useful since we have the
+  ``TemplateLoader`` mechanism already.
+
+- The compiled template module now contains an ``initialize`` function
+  which takes values that map to the template builtins. The return
+  value of this function is a dictionary that contains the render
+  functions.
+
+Bugfixes:
+
+- The file-based template class no longer verifies the existance of a
+  template file (using ``os.lstat``). This now happens implicitly if
+  eager parsing is enabled, or otherwise when first needed (e.g. at
+  render time).
+
+  This is classified as a bug fix because the previous behavior was
+  probably not what you'd expect, especially if an application
+  initializes a lot of templates without needing to render them
+  immediately.
+
+2.1.1 (2011-07-28)
+------------------
+
+Features:
+
+- Improved exception display. The expression string is now shown in
+  the context of the original source (if available) with a marker
+  string indicating the location of the expression in the template
+  source.
+
+Bugfixes:
+
+- The ``structure`` insertion mode now correctly decodes entities for
+  any expression type (including ``string:``). This fixes issue #30.
+
+- Don't show internal variables in the exception formatter variable
+  listing.
+
+2.1 (2011-07-25)
+----------------
+
+Features:
+
+- Expression interpolation (using the ``${...}`` operator and
+  previously also ``$identifier``) now requires braces everywhere
+  except inside the ``string:`` expression type.
+
+  This change is motivated by a number of legacy templates in which
+  the interpolation format without braces ``$identifier`` appears as
+  text.
+
+2.0.2 (2011-07-25)
+------------------
+
+Bugfixes:
+
+- Don't use dynamic variable scope for lambda-scoped variables (#27).
+
+- Avoid duplication of exception class and message in traceback.
+
+- Fixed issue where a ``metal:fill-slot`` would be ignored if a macro
+  was set to be used on the same element (#16).
+
+2.0.1 (2011-07-23)
+------------------
+
+Bugfixes:
+
+- Fixed issue where global variable definition from macro slots would
+  fail (they would instead be local). This also affects error
+  reporting from inside slots because this would be recorded
+  internally as a global.
+
+- Fixed issue with template cache digest (used for filenames); modules
+  are now invalidated whenever any changes are made to the
+  distribution set available (packages on ``sys.path``).
+
+- Fixed exception handler to better let exceptions propagate through
+  the renderer.
+
+- The disk-based module compiler now mangles template source filenames
+  such that the output Python module is valid and at root level (dots
+  and hyphens are replaced by an underscore). This fixes issue #17.
+
+- Fixed translations (i18n) on Python 2.5.
+
+2.0 (2011-07-14)
+----------------
+
+- Point release.
+
+2.0-rc14 (2011-07-13)
+---------------------
+
+Bugfixes:
+
+- The tab character (``\t``) is now parsed correctly when used inside
+  tags.
+
+Features:
+
+- The ``RepeatDict`` class now works as a proxy behind a seperate
+  dictionary instance.
+
+- Added template constructor option ``keep_body`` which is a flag
+  (also available as a class attribute) that controls whether to save
+  the template body input in the ``body`` attribute.
+
+  This is disabled by default, unless debug-mode is enabled.
+
+- The page template loader class now accepts an optional ``formats``
+  argument which can be used to select an alternative template class.
+
+2.0-rc13 (2011-07-07)
+---------------------
+
+Bugfixes:
+
+- The backslash character (followed by optional whitespace and a line
+  break) was not correctly interpreted as a continuation for Python
+  expressions.
+
+Features:
+
+- The Python expression implementation is now more flexible for
+  external subclassing via a new ``parse`` method.
+
+2.0-rc12 (2011-07-04)
+---------------------
+
+Bugfixes:
+
+- Initial keyword arguments passed to a template now no longer "leak"
+  into the template variable space after a macro call.
+
+- An unexpected end tag is now an unrecoverable error.
+
+Features:
+
+- Improve exception output.
+
+2.0-rc11 (2011-05-26)
+---------------------
+
+Bugfixes:
+
+- Fixed issue where variable names that begin with an underscore were
+  seemingly allowed, but their use resulted in a compiler error.
+
+Features:
+
+- Template variable names are now allowed to be prefixed with a single
+  underscore, but not two or more (reserved for internal use).
+
+  Examples of valid names::
+
+    item
+    ITEM
+    _item
+    camelCase
+    underscore_delimited
+    help
+
+- Added support for Genshi's comment "drop" syntax::
+
+    <!--! This comment will be dropped -->
+
+  Note the additional exclamation (!) character.
+
+  This fixes addresses issue #10.
+
+2.0-rc10 (2011-05-24)
+---------------------
+
+Bugfixes:
+
+- The ``tal:attributes`` statement now correctly operates
+  case-insensitive. The attribute name given in the statement will
+  replace an existing attribute with the same name, without respect to
+  case.
+
+Features:
+
+- Added ``meta:interpolation`` statement to control expression
+  interpolation setting.
+
+  Strings that disable the setting: ``"off"`` and ``"false"``.
+  Strings that enable the setting: ``"on"`` and ``"true"``.
+
+- Expression interpolation now works inside XML comments.
+
+2.0-rc9 (2011-05-05)
+--------------------
+
+Features:
+
+- Better debugging support for string decode and conversion. If a
+  naive join fails, each element in the output will now be attempted
+  coerced to unicode to try and trigger the failure near to the bad
+  string.
+
+2.0-rc8 (2011-04-11)
+--------------------
+
+Bugfixes:
+
+- If a macro defines two slots with the same name, a caller will now
+  fill both with a single usage.
+
+- If a valid of ``None`` is provided as the translation function
+  argument, we now fall back to the class default.
+
+2.0-rc7 (2011-03-29)
+--------------------
+
+Bugfixes:
+
+- Fixed issue with Python 2.5 compatibility AST. This affected at
+  least PyPy 1.4.
+
+Features:
+
+- The ``auto_reload`` setting now defaults to the class value; the
+  base template class gives a default value of
+  ``chameleon.config.AUTO_RELOAD``. This change allows a subclass to
+  provide a custom default value (such as an application-specific
+  debug mode setting).
+
+
+2.0-rc6 (2011-03-19)
+--------------------
+
+Features:
+
+- Added support for ``target_language`` keyword argument to render
+  method. If provided, the argument will be curried onto the
+  translation function.
+
+Bugfixes:
+
+- The HTML entities 'lt', 'gt' and 'quot' appearing inside content
+  subtition expressions are now translated into their native character
+  values. This fixes an issue where you could not dynamically create
+  elements using the ``structure`` (which is possible in ZPT). The
+  need to create such structure stems from the lack of an expression
+  interpolation operator in ZPT.
+
+- Fixed duplicate file pointer issue with test suite (affected Windows
+  platforms only). This fixes issue #9.
+  [oliora]
+
+- Use already open file using ``os.fdopen`` when trying to write out
+  the module source. This fixes LP #731803.
+
+
+2.0-rc5 (2011-03-07)
+--------------------
+
+Bugfixes:
+
+- Fixed a number of issues concerning the escaping of attribute
+  values:
+
+  1) Static attribute values are now included as they appear in the
+     source.
+
+     This means that invalid attribute values such as ``"true &&
+     false"`` are now left alone. It's not the job of the template
+     engine to correct such markup, at least not in the default mode
+     of operation.
+
+  2) The string expression compiler no longer unescapes
+     values. Instead, this is left to each expression
+     compiler. Currently only the Python expression compiler unescapes
+     its input.
+
+  3) The dynamic escape code sequence now correctly only replaces
+     ampersands that are part of an HTML escape format.
+
+Imports:
+
+- The page template classes and the loader class can now be imported
+  directly from the ``chameleon`` module.
+
+Features:
+
+- If a custom template loader is not provided, relative paths are now
+  resolved using ``os.abspath`` (i.e. to the current working
+  directory).
+
+- Absolute paths are normalized using ``os.path.normpath`` and
+  ``os.path.expanduser``. This ensures that all paths are kept in
+  their "canonical" form.
+
+
+2.0-rc4 (2011-03-03)
+--------------------
+
+Bugfixes:
+
+- Fixed an issue where the output of an end-to-end string expression
+  would raise an exception if the expression evaluated to ``None`` (it
+  should simply output nothing).
+
+- The ``convert`` function (which is configurable on the template
+  class level) now defaults to the ``translate`` function (at
+  run-time).
+
+  This fixes an issue where message objects were not translated (and
+  thus converted to a string) using the a provided ``translate``
+  function.
+
+- Fixed string interpolation issue where an expression immediately
+  succeeded by a right curly bracket would not parse.
+
+  This fixes issue #5.
+
+- Fixed error where ``tal:condition`` would be evaluated after
+  ``tal:repeat``.
+
+Features:
+
+- Python expression is now a TALES expression. That means that the
+  pipe operator can be used to chain two or more expressions in a
+  try-except sequence.
+
+  This behavior was ported from the 1.x series. Note that while it's
+  still possible to use the pipe character ("|") in an expression, it
+  must now be escaped.
+
+- The template cache can now be shared by multiple processes.
+
+
+2.0-rc3 (2011-03-02)
+--------------------
+
+Bugfixes:
+
+- Fixed ``atexit`` handler.
+
+  This fixes issue #3.
+
+- If a cache directory is specified, it will now be used even when not
+  in debug mode.
+
+- Allow "comment" attribute in the TAL namespace.
+
+  This fixes an issue in the sense that the reference engine allows
+  any attribute within the TAL namespace. However, only "comment" is
+  in common use.
+
+- The template constructor now accepts a flag ``debug`` which puts the
+  template *instance* into debug-mode regardless of the global
+  setting.
+
+  This fixes issue #1.
+
+Features:
+
+- Added exception handler for exceptions raised while evaluating an
+  expression.
+
+  This handler raises (or attempts to) a new exception of the type
+  ``RenderError``, with an additional base class of the original
+  exception class. The string value of the exception is a formatted
+  error message which includes the expression that caused the
+  exception.
+
+  If we are unable to create the exception class, the original
+  exception is re-raised.
+
+2.0-rc2 (2011-02-28)
+--------------------
+
+- Fixed upload issue.
+
+2.0-rc1 (2011-02-28)
+--------------------
+
+- Initial public release. See documentation for what's new in this
+  series.
diff --git a/lib3/Chameleon-2.9.2/COPYRIGHT.txt b/lib3/Chameleon-2.9.2/COPYRIGHT.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/COPYRIGHT.txt
@@ -0,0 +1,7 @@
+Copyright (c) 2011 Malthe Borch and Contributors. All Rights Reserved.
+
+Portions (c) Zope Foundation and contributors (http://www.zope.org/).
+
+Portions (c) Edgewall Software.
+
+Portions (c) 2008 Armin Ronacher.
diff --git a/lib3/Chameleon-2.9.2/LICENSE.txt b/lib3/Chameleon-2.9.2/LICENSE.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/LICENSE.txt
@@ -0,0 +1,185 @@
+The majority of the code in Chameleon is supplied under this license:
+
+  A copyright notice accompanies this license document that identifies
+  the copyright holders.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are
+  met:
+
+  1.  Redistributions in source code must retain the accompanying
+      copyright notice, this list of conditions, and the following
+      disclaimer.
+
+  2.  Redistributions in binary form must reproduce the accompanying
+      copyright notice, this list of conditions, and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+  3.  Names of the copyright holders must not be used to endorse or
+      promote products derived from this software without prior
+      written permission from the copyright holders.
+
+  4.  If any files are modified, you must cause the modified files to
+      carry prominent notices stating that you changed the files and
+      the date of any change.
+
+  Disclaimer
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND
+    ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+    TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+Portions of the code in Chameleon are supplied under the ZPL (headers
+within individiual files indicate that these portions are licensed
+under the ZPL):
+
+  Zope Public License (ZPL) Version 2.1
+  -------------------------------------
+
+  A copyright notice accompanies this license document that
+  identifies the copyright holders.
+
+  This license has been certified as open source. It has also
+  been designated as GPL compatible by the Free Software
+  Foundation (FSF).
+
+  Redistribution and use in source and binary forms, with or
+  without modification, are permitted provided that the
+  following conditions are met:
+
+  1. Redistributions in source code must retain the
+     accompanying copyright notice, this list of conditions,
+     and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the accompanying
+     copyright notice, this list of conditions, and the
+     following disclaimer in the documentation and/or other
+     materials provided with the distribution.
+
+  3. Names of the copyright holders must not be used to
+     endorse or promote products derived from this software
+     without prior written permission from the copyright
+     holders.
+
+  4. The right to distribute this software or to use it for
+     any purpose does not give you the right to use
+     Servicemarks (sm) or Trademarks (tm) of the copyright
+     holders. Use of them is covered by separate agreement
+     with the copyright holders.
+
+  5. If any files are modified, you must cause the modified
+     files to carry prominent notices stating that you changed
+     the files and the date of any change.
+
+  Disclaimer
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS''
+    AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+    NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+    NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+    OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+    DAMAGE.
+
+Portions of the code in Chameleon are supplied under the BSD license
+(headers within individiual files indicate that these portions are
+licensed under this license):
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+   3. The name of the author may not be used to endorse or promote
+      products derived from this software without specific prior
+      written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Portions of the code in Chameleon are supplied under the Python
+License (headers within individiual files indicate that these portions
+are licensed under this license):
+
+  PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+  --------------------------------------------
+
+  1. This LICENSE AGREEMENT is between the Python Software Foundation
+  ("PSF"), and the Individual or Organization ("Licensee") accessing and
+  otherwise using this software ("Python") in source or binary form and
+  its associated documentation.
+
+  2. Subject to the terms and conditions of this License Agreement, PSF
+  hereby grants Licensee a nonexclusive, royalty-free, world-wide
+  license to reproduce, analyze, test, perform and/or display publicly,
+  prepare derivative works, distribute, and otherwise use Python
+  alone or in any derivative version, provided, however, that PSF's
+  License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+  2001, 2002, 2003, 2004 Python Software Foundation; All Rights Reserved"
+  are retained in Python alone or in any derivative version prepared
+  by Licensee.
+
+  3. In the event Licensee prepares a derivative work that is based on
+  or incorporates Python or any part thereof, and wants to make
+  the derivative work available to others as provided herein, then
+  Licensee hereby agrees to include in any such work a brief summary of
+  the changes made to Python.
+
+  4. PSF is making Python available to Licensee on an "AS IS"
+  basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+  IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+  DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+  FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+  INFRINGE ANY THIRD PARTY RIGHTS.
+
+  5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+  FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+  A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+  OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+  6. This License Agreement will automatically terminate upon a material
+  breach of its terms and conditions.
+
+  7. Nothing in this License Agreement shall be deemed to create any
+  relationship of agency, partnership, or joint venture between PSF and
+  Licensee.  This License Agreement does not grant permission to use PSF
+  trademarks or trade name in a trademark sense to endorse or promote
+  products or services of Licensee, or any third party.
+
+  8. By copying, installing or otherwise using Python, Licensee
+  agrees to be bound by the terms and conditions of this License
+  Agreement.
diff --git a/lib3/Chameleon-2.9.2/Makefile b/lib3/Chameleon-2.9.2/Makefile
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/Makefile
@@ -0,0 +1,89 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    = docs
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
+
+.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  dirhtml   to make HTML files named index.html in directories"
+	@echo "  pickle    to make pickle files"
+	@echo "  json      to make JSON files"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  qthelp    to make HTML files and a qthelp project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Chameleon.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Chameleon.qhc"
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/lib3/Chameleon-2.9.2/PKG-INFO b/lib3/Chameleon-2.9.2/PKG-INFO
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/PKG-INFO
@@ -0,0 +1,1122 @@
+Metadata-Version: 1.1
+Name: Chameleon
+Version: 2.9.2
+Summary: Fast HTML/XML Template Compiler.
+Home-page: http://www.pagetemplates.org/
+Author: Malthe Borch
+Author-email: mborch at gmail.com
+License: BSD-like (http://repoze.org/license.html)
+Description: Overview
+        ========
+        
+        Chameleon is an HTML/XML template engine for `Python
+        <http://www.python.org>`_. It uses the *page templates* language.
+        
+        You can use it in any Python web application with just about any
+        version of Python (2.5 and up, including 3.x and `pypy
+        <http://pypy.org>`_).
+        
+        Visit the `website <http://pagetemplates.org>`_ for more information
+        or the `documentation <http://pagetemplates.org/docs/latest/>`_.
+        
+        License and Copyright
+        ---------------------
+        
+        This software is made available as-is under a BSD-like license [1]_
+        (see included copyright notice).
+        
+        
+        Notes
+        -----
+        
+        .. [1] This software is licensed under the `Repoze
+               <http://repoze.org/license.html>`_ license.
+        
+        
+        Changes
+        =======
+        
+        2.9.2 (2012-06-06)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed a PyPy incompatibility.
+        
+        - Fixed issue #109 which caused testing failures on some platforms.
+        
+        2.9.1 (2012-06-01)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed issue #103. The ``tal:on-error`` statement now always adds an
+          explicit end-tag to the element, even with a substitution content of
+          nothing.
+        
+        - Fixed issue #113. The ``tal:on-error`` statement now works correctly
+          also for dynamic attributes. That is, the fallback tag now includes
+          only static attributes.
+        
+        - Fixed name error which prevented the benchmark from running
+          correctly.
+        
+        Compatibility:
+        
+        - Fixed deprecation warning on Python 3 for zope interface implements
+          declaration. This fixes issue #116.
+        
+        2.9.0 (2012-05-31)
+        ------------------
+        
+        Features:
+        
+        - The translation function now gets the ``econtext`` argument as the
+          value for ``context``. Note that historically, this was usually an
+          HTTP request which might provide language negotiation data through a
+          dictionary interface.
+          [alvinyue]
+        
+        Bugfixes:
+        
+        - Fixed import alias issue which would lead to a syntax error in
+          generated Python code. Fixes issue #114.
+        
+        2.8.5 (2012-05-02)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed minor installation issues on Python 2.5 and 3.
+          [ppaez]
+        
+        - Ensure output is unicode even when trivial (an empty string).
+        
+        2.8.4 (2012-04-18)
+        ------------------
+        
+        Features:
+        
+        - In exception output, long filenames are now truncated to 60
+          characters of output, preventing line wrap which makes it difficult
+          to scan the exception output.
+        
+        Bugfixes:
+        
+        - Include filename and location in exception output for exceptions
+          raised during compilation.
+        
+        - If a trivial translation substitution variable is given (i.e. an
+          empty string), simply ignore it. This fixes issue #106.
+        
+        2.8.3 (2012-04-16)
+        ------------------
+        
+        Features:
+        
+        - Log template source on debug-level before cooking.
+        
+        - The `target_language` argument, if given, is now available as a
+          variable in templates.
+        
+        2.8.2 (2012-03-30)
+        ------------------
+        
+        Features:
+        
+        - Temporary caches used in debug mode are cleaned up eagerly, rather
+          than waiting for process termination.
+          [mitchellrj]
+        
+        Bugfixes:
+        
+        - The `index`, `start` and `end` methods on the TAL repeat object are
+          now callable. This fixes an incompatibility with ZPT.
+        
+        - The loader now correctly handles absolute paths on Windows.
+          [rdale]
+        
+        2.8.1 (2012-03-29)
+        ------------------
+        
+        Features:
+        
+        - The exception formatter now lists errors in 'wrapping order'. This
+          means that the innermost, and presumably most relevant exception is
+          shown last.
+        
+        Bugfixes:
+        
+        - The exception formatter now correctly recognizes nested errors and
+          does not rewrap the dynamically generated exception class.
+        
+        - The exception formatter now correctly sets the ``__module__``
+          attribute to that of the original exception class.
+        
+        2.8.0 (2012-02-29)
+        ------------------
+        
+        Features:
+        
+        - Added support for code blocks using the `<?python ... ?>` processing
+          instruction syntax.
+        
+          The scope is name assignments is up until the nearest macro
+          definition, or the template itself if macros are not used.
+        
+        Bugfixes:
+        
+        - Fall back to the exception class' ``__new__`` method to safely
+          create an exception object that is not implemented in Python.
+        
+        - The exception formatter now keeps track of already formatted
+          exceptions, and ignores them from further output.
+        
+        2.7.4 (2012-02-27)
+        ------------------
+        
+        - The error handler now invokes the ``__init__`` method of
+          ``BaseException`` instead of the possibly overriden method (which
+          may take required arguments). This fixes issue #97.
+          [j23d, malthe]
+        
+        2.7.3 (2012-01-16)
+        ------------------
+        
+        Bugfixes:
+        
+        - The trim whitespace option now correctly trims actual whitespace to
+          a single character, appearing either to the left or to the right of
+          an element prefix or suffix string.
+        
+        2.7.2 (2012-01-08)
+        ------------------
+        
+        Features:
+        
+        - Added option ``trim_attribute_space`` that decides whether attribute
+          whitespace is stripped (at most down to a single space). This option
+          exists to provide compatibility with the reference
+          implementation. Fixes issue #85.
+        
+        Bugfixes:
+        
+        - Ignore unhashable builtins when generating a reverse builtin
+          map to quickly look up a builtin value.
+          [malthe]
+        
+        - Apply translation mapping even when a translation function is not
+          available. This fixes issue #83.
+          [malthe]
+        
+        - Fixed issue #80. The translation domain for a slot is defined by the
+          source document, i.e. the template providing the content for a slot
+          whether it be the default or provided through ``metal:fill-slot``.
+          [jcbrand]
+        
+        - In certain circumstances, a Unicode non-breaking space character would cause
+          a define clause to fail to parse.
+        
+        2.7.1 (2011-12-29)
+        ------------------
+        
+        Features:
+        
+        - Enable expression interpolation in CDATA.
+        
+        - The page template class now implements dictionary access to macros::
+        
+             template[name]
+        
+          This is a short-hand for::
+        
+             template.macros[name]
+        
+        Bugfixes:
+        
+        - An invalid define clause would be silently ignored; we now raise a
+          language error exception. This fixes issue #79.
+        
+        - Fixed regression where ``${...}`` interpolation expressions could
+          not span multiple lines. This fixes issue #77.
+        
+        2.7.0 (2011-12-13)
+        ------------------
+        
+        Features:
+        
+        - The ``load:`` expression now derives from the string expression such
+          that the ``${...}`` operator can be used for expression
+          interpolation.
+        
+        - The ``load:`` expression now accepts asset specs; these are resolved
+          by the ``pkg_resources.resource_filename`` function::
+        
+            <package_name>:<path>
+        
+          An example from the test suite::
+        
+            chameleon:tests/inputs/hello_world.pt
+        
+        Bugfixes:
+        
+        - If an attribute name for translation was not a valid Python
+          identifier, the compiler would generate invalid code. This has been
+          fixed, and the compiler now also throws an exception if an attribute
+          specification contains a comma. (Note that the only valid separator
+          character is the semicolon, when specifying attributes for
+          translation via the ``i18n:translate`` statement). This addresses
+          issue #76.
+        
+        2.6.2 (2011-12-08)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed issue where ``tal:on-error`` would not respect
+          ``tal:omit-tag`` or namespace elements which are omitted by default
+          (such as ``<tal:block />``).
+        
+        - Fixed issue where ``macros`` attribute would not be available on
+          file-based templates due to incorrect initialization.
+        
+        - The ``TryExcept`` and ``TryFinally`` AST nodes are not available on
+          Python 3.3. These have been aliased to ``Try``. This fixes issue
+          #75.
+        
+        Features:
+        
+        - The TAL repeat item now makes a security declaration that grants
+          access to unprotected subobjects on the Zope 2 platform::
+        
+            __allow_access_to_unprotected_subobjects__ = True
+        
+          This is required for legacy compatibility and does not affect other
+          environments.
+        
+        - The template object now has a method ``write(body)`` which
+          explicitly decodes and cooks a string input.
+        
+        - Added configuration option ``loader_class`` which sets the class
+          used to create the template loader object.
+        
+          The class (essentially a callable) is created at template
+          construction time.
+        
+        2.6.1 (2011-11-30)
+        ------------------
+        
+        Bugfixes:
+        
+        - Decode HTML entities in expression interpolation strings. This fixes
+          issue #74.
+        
+        - Allow ``xml`` and ``xmlns`` attributes on TAL, I18N and METAL
+          namespace elements. This fixes issue #73.
+        
+        2.6.0 (2011-11-24)
+        ------------------
+        
+        Features:
+        
+        - Added support for implicit translation:
+        
+          The ``implicit_i18n_translate`` option enables implicit translation
+          of text. The ``implicit_i18n_attributes`` enables implicit
+          translation of attributes. The latter must be a set and for an
+          attribute to be implicitly translated, its lowercase string value
+          must be included in the set.
+        
+        - Added option ``strict`` (enabled by default) which decides whether
+          expressions are required to be valid at compile time. That is, if
+          not set, an exception is only raised for an invalid expression at
+          evaluation time.
+        
+        - An expression error now results in an exception only if the
+          expression is attempted evaluated during a rendering.
+        
+        - Added a configuration option ``prepend_relative_search_path`` which
+          decides whether the path relative to a file-based template is
+          prepended to the load search path. The default is ``True``.
+        
+        - Added a configuration option ``search_path`` to the file-based
+          template class, which adds additional paths to the template load
+          instance bound to the ``load:`` expression. The option takes a
+          string path or an iterable yielding string paths. The default value
+          is the empty set.
+        
+        Bugfixes:
+        
+        - Exception instances now support pickle/unpickle.
+        
+        - An attributes in i18n:attributes no longer needs to match an
+          existing or dynamic attribute in order to appear in the
+          element. This fixes issue #66.
+        
+        2.5.3 (2011-10-23)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue where a nested macro slot definition would fail even
+          though there existed a parent macro definition. This fixes issue
+          #69.
+        
+        2.5.2 (2011-10-12)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue where technically invalid input would result in a
+          compiler error.
+        
+        Features:
+        
+        - The markup class now inherits from the unicode string type such that
+          it's compatible with the string interface.
+        
+        2.5.1 (2011-09-29)
+        ------------------
+        
+        Bugfixes:
+        
+        - The symbol names "convert", "decode" and "translate" are now no
+          longer set as read-only *compiler internals*. This fixes issue #65.
+        
+        - Fixed an issue where a macro extension chain nested two levels (a
+          template uses a macro that extends a macro) would lose the middle
+          slot definitions if slots were defined nested.
+        
+          The compiler now throws an error if a nested slot definition is used
+          outside a macro extension context.
+        
+        2.5.0 (2011-09-23)
+        ------------------
+        
+        Features:
+        
+        - An expression type ``structure:`` is now available which wraps the
+          expression result as *structure* such that it is not escaped on
+          insertion, e.g.::
+        
+            <div id="content">
+               ${structure: context.body}
+            </div>
+        
+          This also means that the ``structure`` keyword for ``tal:content``
+          and ``tal:replace`` now has an alternative spelling via the
+          expression type ``structure:``.
+        
+        - The string-based template constructor now accepts encoded input.
+        
+        2.4.6 (2011-09-23)
+        ------------------
+        
+        Bugfixes:
+        
+        - The ``tal:on-error`` statement should catch all exceptions.
+        
+        - Fixed issue that would prevent escaping of interpolation expression
+          values appearing in text.
+        
+        2.4.5 (2011-09-21)
+        ------------------
+        
+        Bugfixes:
+        
+        - The ``tal:on-error`` handler should have a ``error`` variable
+          defined that has the value of the exception thrown.
+        
+        - The ``tal:on-error`` statement is a substitution statement and
+          should support the "text" and "structure" insertion methods.
+        
+        2.4.4 (2011-09-15)
+        ------------------
+        
+        Bugfixes:
+        
+        - An encoding specified in the XML document preamble is now read and
+          used to decode the template input to unicode. This fixes issue #55.
+        
+        - Encoded expression input on Python 3 is now correctly
+          decoded. Previously, the string representation output would be
+          included instead of an actually decoded string.
+        
+        - Expression result conversion steps are now correctly included in
+          error handling such that the exception output points to the
+          expression location.
+        
+        2.4.3 (2011-09-13)
+        ------------------
+        
+        Features:
+        
+        - When an encoding is provided, pass the 'ignore' flag to avoid
+          decoding issues with bad input.
+        
+        Bugfixes:
+        
+        - Fixed pypy compatibility issue (introduced in previous release).
+        
+        2.4.2 (2011-09-13)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue in the compiler where an internal variable (such as a
+          translation default value) would be cached, resulting in variable
+          scope corruption (see issue #49).
+        
+        2.4.1 (2011-09-08)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue where a default value for an attribute would
+          sometimes spill over into another attribute.
+        
+        - Fixed issue where the use of the ``default`` name in an attribute
+          interpolation expression would print the attribute value. This is
+          unexpected, because it's an expression, not a static text suitable
+          for output. An attribute value of ``default`` now correctly drops
+          the attribute.
+        
+        2.4.0 (2011-08-22)
+        ------------------
+        
+        Features:
+        
+        - Added an option ``boolean_attributes`` to evaluate and render a
+          provided set of attributes using a boolean logic: if the attribute
+          is a true value, the value will be the attribute name, otherwise the
+          attribute is dropped.
+        
+          In the reference implementation, the following attributes are
+          configured as boolean values when the template is rendered in
+          HTML-mode::
+        
+              "compact", "nowrap", "ismap", "declare", "noshade",
+              "checked", "disabled", "readonly", "multiple", "selected",
+              "noresize", "defer"
+        
+          Note that in Chameleon, these attributes must be manually provided.
+        
+        Bugfixes:
+        
+        - The carriage return character (used on Windows platforms) would
+          incorrectly be included in Python comments.
+        
+          It is now replaced with a line break.
+        
+          This fixes issue #44.
+        
+        2.3.8 (2011-08-19)
+        ------------------
+        
+        - Fixed import error that affected Python 2.5 only.
+        
+        2.3.7 (2011-08-19)
+        ------------------
+        
+        Features:
+        
+        - Added an option ``literal_false`` that disables the default behavior
+          of dropping an attribute for a value of ``False`` (in addition to
+          ``None``). This modified behavior is the behavior exhibited in
+          reference implementation.
+        
+        Bugfixes:
+        
+        - Undo attribute special HTML attribute behavior (see previous
+          release).
+        
+          This turned out not to be a compatible behavior; rather, boolean
+          values should simply be coerced to a string.
+        
+          Meanwhile, the reference implementation does support an HTML mode in
+          which the special attribute behavior is exhibited.
+        
+          We do not currently support this mode.
+        
+        2.3.6 (2011-08-18)
+        ------------------
+        
+        Features:
+        
+        - Certain HTML attribute names now have a special behavior for a
+          attribute value of ``True`` (or ``default`` if no default is
+          defined). For these attributes, this return value will result in the
+          name being printed as the value::
+        
+            <input type="input" tal:attributes="checked True" />
+        
+          will be rendered as::
+        
+            <input type="input" checked="checked" />
+        
+          This behavior is compatible with the reference implementation.
+        
+        2.3.5 (2011-08-18)
+        ------------------
+        
+        Features:
+        
+        - Added support for the set operator (``{item, item, ...}``).
+        
+        Bugfixes:
+        
+        - If macro is defined on the same element as a translation name, this
+          no longer results in a "translation name not allowed outside
+          translation" error. This fixes issue #43.
+        
+        - Attribute fallback to dictionary lookup now works on multiple items
+          (e.g. ``d1.d2.d2``). This fixes issue #42.
+        
+        2.3.4 (2011-08-16)
+        ------------------
+        
+        Features:
+        
+        - When inserting content in either attributes or text, a value of
+          ``True`` (like ``False`` and ``None``) will result in no
+          action.
+        
+        - Use statically assigned variables for ``"attrs"`` and
+          ``"default"``. This change yields a performance improvement of
+          15-20%.
+        
+        - The template loader class now accepts an optional argument
+          ``default_extension`` which accepts a filename extension which will
+          be appended to the filename if there's not already an extension.
+        
+        Bugfixes:
+        
+        - The default symbol is now ``True`` for an attribute if the attribute
+          default is not provided. Note that the result is that the attribute
+          is dropped. This fixes issue #41.
+        
+        - Fixed an issue where assignment to a variable ``"type"`` would
+          fail. This fixes issue #40.
+        
+        - Fixed an issue where an (unsuccesful) assignment for a repeat loop
+          to a compiler internal name would not result in an error.
+        
+        - If the translation function returns the identical object, manually
+          coerce it to string. This fixes a compatibility issue with
+          translation functions which do not convert non-string objects to a
+          string value, but simply return them unchanged.
+        
+        2.3.3 (2011-08-15)
+        ------------------
+        
+        Features:
+        
+        - The ``load:`` expression now passes the initial keyword arguments to
+          its template loader (e.g. ``auto_reload`` and ``encoding``).
+        
+        - In the exception output, string variable values are now limited to a
+          limited output of characters, single line only.
+        
+        Bugfixes:
+        
+        - Fixed horizontal alignment of exception location info
+          (i.e. 'String:', 'Filename:' and 'Location:') such that they match
+          the template exception formatter.
+        
+        2.3.2 (2011-08-11)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed issue where i18n:domain would not be inherited through macros
+          and slots. This fixes issue #37.
+        
+        2.3.1 (2011-08-11)
+        ------------------
+        
+        Features:
+        
+        - The ``Builtin`` node type may now be used to represent any Python
+          local or global name. This allows expression compilers to refer to
+          e.g. ``get`` or ``getitem``, or to explicit require a builtin object
+          such as one from the ``extra_builtins`` dictionary.
+        
+        Bugfixes:
+        
+        - Builtins which are not explicitly disallowed may now be redefined
+          and used as variables (e.g. ``nothing``).
+        
+        - Fixed compiler issue with circular node annotation loop.
+        
+        2.3 (2011-08-10)
+        ----------------
+        
+        Features:
+        
+        - Added support for the following syntax to disable inline evaluation
+          in a comment:
+        
+            <!--? comment appears verbatim (no ${...} evaluation) -->
+        
+          Note that the initial question mark character (?) will be omitted
+          from output.
+        
+        - The parser now accepts '<' and '>' in attributes. Note that this is
+          invalid markup. Previously, the '<' would not be accepted as a valid
+          attribute value, but this would result in an 'unexpected end tag'
+          error elsewhere. This fixes issue #38.
+        
+        - The expression compiler now provides methods ``assign_text`` and
+          ``assign_value`` such that a template engine might configure this
+          value conversion to support e.g. encoded strings.
+        
+          Note that currently, the only client for the ``assign_text`` method
+          is the string expression type.
+        
+        - Enable template loader for string-based template classes. Note that
+          the ``filename`` keyword argument may be provided on initialization
+          to identify the template source by filename. This fixes issue #36.
+        
+        - Added ``extra_builtins`` option to the page template class. These
+          builtins are added to the default builtins dictionary at cook time
+          and may be provided at initialization using the ``extra_builtins``
+          keyword argument.
+        
+        Bugfixes:
+        
+        - If a translation domain is set for a fill slot, use this setting
+          instead of the macro template domain.
+        
+        - The Python expression compiler now correctly decodes HTML entities
+          ``'gt'`` and ``'lt'``. This fixes issue #32.
+        
+        - The string expression compiler now correctly handles encoded text
+          (when support for encoded strings is enabled). This fixes issue #35.
+        
+        - Fixed an issue where setting the ``filename`` attribute on a
+          file-based template would not automatically cause an invalidation.
+        
+        - Exceptions raised by Chameleon can now be copied via
+          ``copy.copy``. This fixes issue #36.
+          [leorochael]
+        
+        - If copying the exception fails in the exception handler, simply
+          re-raise the original exception and log a warning.
+        
+        2.2 (2011-07-28)
+        ----------------
+        
+        Features:
+        
+        - Added new expression type ``load:`` that allows loading a
+          template. Both relative and absolute paths are supported. If the
+          path given is relative, then it will be resolved with respect to the
+          directory of the template.
+        
+        - Added support for dynamic evaluation of expressions.
+        
+          Note that this is to support legacy applications. It is not
+          currently wired into the provided template classes.
+        
+        - Template classes now have a ``builtins`` attribute which may be used
+          to define built-in variables always available in the template
+          variable scope.
+        
+        Incompatibilities:
+        
+        - The file-based template class no longer accepts a parameter
+          ``loader``. This parameter would be used to load a template from a
+          relative path, using a ``find(filename)`` method. This was however,
+          undocumented, and probably not very useful since we have the
+          ``TemplateLoader`` mechanism already.
+        
+        - The compiled template module now contains an ``initialize`` function
+          which takes values that map to the template builtins. The return
+          value of this function is a dictionary that contains the render
+          functions.
+        
+        Bugfixes:
+        
+        - The file-based template class no longer verifies the existance of a
+          template file (using ``os.lstat``). This now happens implicitly if
+          eager parsing is enabled, or otherwise when first needed (e.g. at
+          render time).
+        
+          This is classified as a bug fix because the previous behavior was
+          probably not what you'd expect, especially if an application
+          initializes a lot of templates without needing to render them
+          immediately.
+        
+        2.1.1 (2011-07-28)
+        ------------------
+        
+        Features:
+        
+        - Improved exception display. The expression string is now shown in
+          the context of the original source (if available) with a marker
+          string indicating the location of the expression in the template
+          source.
+        
+        Bugfixes:
+        
+        - The ``structure`` insertion mode now correctly decodes entities for
+          any expression type (including ``string:``). This fixes issue #30.
+        
+        - Don't show internal variables in the exception formatter variable
+          listing.
+        
+        2.1 (2011-07-25)
+        ----------------
+        
+        Features:
+        
+        - Expression interpolation (using the ``${...}`` operator and
+          previously also ``$identifier``) now requires braces everywhere
+          except inside the ``string:`` expression type.
+        
+          This change is motivated by a number of legacy templates in which
+          the interpolation format without braces ``$identifier`` appears as
+          text.
+        
+        2.0.2 (2011-07-25)
+        ------------------
+        
+        Bugfixes:
+        
+        - Don't use dynamic variable scope for lambda-scoped variables (#27).
+        
+        - Avoid duplication of exception class and message in traceback.
+        
+        - Fixed issue where a ``metal:fill-slot`` would be ignored if a macro
+          was set to be used on the same element (#16).
+        
+        2.0.1 (2011-07-23)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed issue where global variable definition from macro slots would
+          fail (they would instead be local). This also affects error
+          reporting from inside slots because this would be recorded
+          internally as a global.
+        
+        - Fixed issue with template cache digest (used for filenames); modules
+          are now invalidated whenever any changes are made to the
+          distribution set available (packages on ``sys.path``).
+        
+        - Fixed exception handler to better let exceptions propagate through
+          the renderer.
+        
+        - The disk-based module compiler now mangles template source filenames
+          such that the output Python module is valid and at root level (dots
+          and hyphens are replaced by an underscore). This fixes issue #17.
+        
+        - Fixed translations (i18n) on Python 2.5.
+        
+        2.0 (2011-07-14)
+        ----------------
+        
+        - Point release.
+        
+        2.0-rc14 (2011-07-13)
+        ---------------------
+        
+        Bugfixes:
+        
+        - The tab character (``\t``) is now parsed correctly when used inside
+          tags.
+        
+        Features:
+        
+        - The ``RepeatDict`` class now works as a proxy behind a seperate
+          dictionary instance.
+        
+        - Added template constructor option ``keep_body`` which is a flag
+          (also available as a class attribute) that controls whether to save
+          the template body input in the ``body`` attribute.
+        
+          This is disabled by default, unless debug-mode is enabled.
+        
+        - The page template loader class now accepts an optional ``formats``
+          argument which can be used to select an alternative template class.
+        
+        2.0-rc13 (2011-07-07)
+        ---------------------
+        
+        Bugfixes:
+        
+        - The backslash character (followed by optional whitespace and a line
+          break) was not correctly interpreted as a continuation for Python
+          expressions.
+        
+        Features:
+        
+        - The Python expression implementation is now more flexible for
+          external subclassing via a new ``parse`` method.
+        
+        2.0-rc12 (2011-07-04)
+        ---------------------
+        
+        Bugfixes:
+        
+        - Initial keyword arguments passed to a template now no longer "leak"
+          into the template variable space after a macro call.
+        
+        - An unexpected end tag is now an unrecoverable error.
+        
+        Features:
+        
+        - Improve exception output.
+        
+        2.0-rc11 (2011-05-26)
+        ---------------------
+        
+        Bugfixes:
+        
+        - Fixed issue where variable names that begin with an underscore were
+          seemingly allowed, but their use resulted in a compiler error.
+        
+        Features:
+        
+        - Template variable names are now allowed to be prefixed with a single
+          underscore, but not two or more (reserved for internal use).
+        
+          Examples of valid names::
+        
+            item
+            ITEM
+            _item
+            camelCase
+            underscore_delimited
+            help
+        
+        - Added support for Genshi's comment "drop" syntax::
+        
+            <!--! This comment will be dropped -->
+        
+          Note the additional exclamation (!) character.
+        
+          This fixes addresses issue #10.
+        
+        2.0-rc10 (2011-05-24)
+        ---------------------
+        
+        Bugfixes:
+        
+        - The ``tal:attributes`` statement now correctly operates
+          case-insensitive. The attribute name given in the statement will
+          replace an existing attribute with the same name, without respect to
+          case.
+        
+        Features:
+        
+        - Added ``meta:interpolation`` statement to control expression
+          interpolation setting.
+        
+          Strings that disable the setting: ``"off"`` and ``"false"``.
+          Strings that enable the setting: ``"on"`` and ``"true"``.
+        
+        - Expression interpolation now works inside XML comments.
+        
+        2.0-rc9 (2011-05-05)
+        --------------------
+        
+        Features:
+        
+        - Better debugging support for string decode and conversion. If a
+          naive join fails, each element in the output will now be attempted
+          coerced to unicode to try and trigger the failure near to the bad
+          string.
+        
+        2.0-rc8 (2011-04-11)
+        --------------------
+        
+        Bugfixes:
+        
+        - If a macro defines two slots with the same name, a caller will now
+          fill both with a single usage.
+        
+        - If a valid of ``None`` is provided as the translation function
+          argument, we now fall back to the class default.
+        
+        2.0-rc7 (2011-03-29)
+        --------------------
+        
+        Bugfixes:
+        
+        - Fixed issue with Python 2.5 compatibility AST. This affected at
+          least PyPy 1.4.
+        
+        Features:
+        
+        - The ``auto_reload`` setting now defaults to the class value; the
+          base template class gives a default value of
+          ``chameleon.config.AUTO_RELOAD``. This change allows a subclass to
+          provide a custom default value (such as an application-specific
+          debug mode setting).
+        
+        
+        2.0-rc6 (2011-03-19)
+        --------------------
+        
+        Features:
+        
+        - Added support for ``target_language`` keyword argument to render
+          method. If provided, the argument will be curried onto the
+          translation function.
+        
+        Bugfixes:
+        
+        - The HTML entities 'lt', 'gt' and 'quot' appearing inside content
+          subtition expressions are now translated into their native character
+          values. This fixes an issue where you could not dynamically create
+          elements using the ``structure`` (which is possible in ZPT). The
+          need to create such structure stems from the lack of an expression
+          interpolation operator in ZPT.
+        
+        - Fixed duplicate file pointer issue with test suite (affected Windows
+          platforms only). This fixes issue #9.
+          [oliora]
+        
+        - Use already open file using ``os.fdopen`` when trying to write out
+          the module source. This fixes LP #731803.
+        
+        
+        2.0-rc5 (2011-03-07)
+        --------------------
+        
+        Bugfixes:
+        
+        - Fixed a number of issues concerning the escaping of attribute
+          values:
+        
+          1) Static attribute values are now included as they appear in the
+             source.
+        
+             This means that invalid attribute values such as ``"true &&
+             false"`` are now left alone. It's not the job of the template
+             engine to correct such markup, at least not in the default mode
+             of operation.
+        
+          2) The string expression compiler no longer unescapes
+             values. Instead, this is left to each expression
+             compiler. Currently only the Python expression compiler unescapes
+             its input.
+        
+          3) The dynamic escape code sequence now correctly only replaces
+             ampersands that are part of an HTML escape format.
+        
+        Imports:
+        
+        - The page template classes and the loader class can now be imported
+          directly from the ``chameleon`` module.
+        
+        Features:
+        
+        - If a custom template loader is not provided, relative paths are now
+          resolved using ``os.abspath`` (i.e. to the current working
+          directory).
+        
+        - Absolute paths are normalized using ``os.path.normpath`` and
+          ``os.path.expanduser``. This ensures that all paths are kept in
+          their "canonical" form.
+        
+        
+        2.0-rc4 (2011-03-03)
+        --------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue where the output of an end-to-end string expression
+          would raise an exception if the expression evaluated to ``None`` (it
+          should simply output nothing).
+        
+        - The ``convert`` function (which is configurable on the template
+          class level) now defaults to the ``translate`` function (at
+          run-time).
+        
+          This fixes an issue where message objects were not translated (and
+          thus converted to a string) using the a provided ``translate``
+          function.
+        
+        - Fixed string interpolation issue where an expression immediately
+          succeeded by a right curly bracket would not parse.
+        
+          This fixes issue #5.
+        
+        - Fixed error where ``tal:condition`` would be evaluated after
+          ``tal:repeat``.
+        
+        Features:
+        
+        - Python expression is now a TALES expression. That means that the
+          pipe operator can be used to chain two or more expressions in a
+          try-except sequence.
+        
+          This behavior was ported from the 1.x series. Note that while it's
+          still possible to use the pipe character ("|") in an expression, it
+          must now be escaped.
+        
+        - The template cache can now be shared by multiple processes.
+        
+        
+        2.0-rc3 (2011-03-02)
+        --------------------
+        
+        Bugfixes:
+        
+        - Fixed ``atexit`` handler.
+        
+          This fixes issue #3.
+        
+        - If a cache directory is specified, it will now be used even when not
+          in debug mode.
+        
+        - Allow "comment" attribute in the TAL namespace.
+        
+          This fixes an issue in the sense that the reference engine allows
+          any attribute within the TAL namespace. However, only "comment" is
+          in common use.
+        
+        - The template constructor now accepts a flag ``debug`` which puts the
+          template *instance* into debug-mode regardless of the global
+          setting.
+        
+          This fixes issue #1.
+        
+        Features:
+        
+        - Added exception handler for exceptions raised while evaluating an
+          expression.
+        
+          This handler raises (or attempts to) a new exception of the type
+          ``RenderError``, with an additional base class of the original
+          exception class. The string value of the exception is a formatted
+          error message which includes the expression that caused the
+          exception.
+        
+          If we are unable to create the exception class, the original
+          exception is re-raised.
+        
+        2.0-rc2 (2011-02-28)
+        --------------------
+        
+        - Fixed upload issue.
+        
+        2.0-rc1 (2011-02-28)
+        --------------------
+        
+        - Initial public release. See documentation for what's new in this
+          series.
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.1
+Classifier: Programming Language :: Python :: 3.2
diff --git a/lib3/Chameleon-2.9.2/README.rst b/lib3/Chameleon-2.9.2/README.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/README.rst
@@ -0,0 +1,25 @@
+Overview
+========
+
+Chameleon is an HTML/XML template engine for `Python
+<http://www.python.org>`_. It uses the *page templates* language.
+
+You can use it in any Python web application with just about any
+version of Python (2.5 and up, including 3.x and `pypy
+<http://pypy.org>`_).
+
+Visit the `website <http://pagetemplates.org>`_ for more information
+or the `documentation <http://pagetemplates.org/docs/latest/>`_.
+
+License and Copyright
+---------------------
+
+This software is made available as-is under a BSD-like license [1]_
+(see included copyright notice).
+
+
+Notes
+-----
+
+.. [1] This software is licensed under the `Repoze
+       <http://repoze.org/license.html>`_ license.
diff --git a/lib3/Chameleon-2.9.2/benchmarks/bm_chameleon.py b/lib3/Chameleon-2.9.2/benchmarks/bm_chameleon.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/benchmarks/bm_chameleon.py
@@ -0,0 +1,128 @@
+#!/usr/bin/python2
+
+"""
+Benchmark for test the performance of Chameleon page template engine.
+"""
+
+__author__ = "mborch at gmail.com (Malthe Borch)"
+
+# Python imports
+import os
+import sys
+import optparse
+import time
+
+# Local imports
+import util
+
+
+def relative(*args):
+    return os.path.join(os.path.dirname(os.path.abspath(__file__)), *args)
+
+sys.path.insert(0, relative('..', 'src'))
+
+# Chameleon imports
+from chameleon import PageTemplate
+
+
+LOREM_IPSUM = """Quisque lobortis hendrerit posuere. Curabitur
+aliquet consequat sapien molestie pretium. Nunc adipiscing luc
+tus mi, viverra porttitor lorem vulputate et. Ut at purus sem,
+sed tincidunt ante. Vestibulum ante ipsum primis in faucibus
+orci luctus et ultrices posuere cubilia Curae; Praesent pulvinar
+sodales justo at congue. Praesent aliquet facilisis nisl a
+molestie. Sed tempus nisl ut augue eleifend tincidunt. Sed a
+lacinia nulla. Cras tortor est, mollis et consequat at,
+vulputate et orci. Nulla sollicitudin"""
+
+BASE_TEMPLATE = '''
+<tal:macros condition="False">
+    <table metal:define-macro="table">
+       <tr tal:repeat="row table">
+          <td tal:repeat="col row">${col}</td>
+       </tr>
+    </table>
+    <img metal:define-macro="img" src="${src}" alt="${alt}" />
+</tal:macros>
+<html metal:define-macro="master">
+    <head><title>${title.strip()}</title></head>
+    <body metal:define-slot="body" />
+</html>
+'''
+
+PAGE_TEMPLATE = '''
+<html metal:define-macro="master" metal:extend-macro="base.macros['master']">
+<body metal:fill-slot="body">
+<table metal:use-macro="base.macros['table']" />
+images:
+<tal:images repeat="nr xrange(img_count)">
+    <img tal:define="src '/foo/bar/baz.png';
+                     alt 'no image :o'"
+         metal:use-macro="base.macros['img']" />
+</tal:images>
+<metal:body define-slot="body" />
+<p tal:repeat="nr paragraphs">${lorem}</p>
+<table metal:use-macro="base.macros['table']" />
+</body>
+</html>
+'''
+
+CONTENT_TEMPLATE = '''
+<html metal:use-macro="page.macros['master']">
+<span metal:define-macro="fun1">fun1</span>
+<span metal:define-macro="fun2">fun2</span>
+<span metal:define-macro="fun3">fun3</span>
+<span metal:define-macro="fun4">fun4</span>
+<span metal:define-macro="fun5">fun5</span>
+<span metal:define-macro="fun6">fun6</span>
+<body metal:fill-slot="body">
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+Nam laoreet justo in velit faucibus lobortis. Sed dictum sagittis
+volutpat. Sed adipiscing vestibulum consequat. Nullam laoreet, ante
+nec pretium varius, libero arcu porttitor orci, id cursus odio nibh
+nec leo. Vestibulum dapibus pellentesque purus, sed bibendum tortor
+laoreet id. Praesent quis sodales ipsum. Fusce ut ligula sed diam
+pretium sagittis vel at ipsum. Nulla sagittis sem quam, et volutpat
+velit. Fusce dapibus ligula quis lectus ultricies tempor. Pellente</p>
+<span metal:use-macro="template.macros['fun1']" />
+<span metal:use-macro="template.macros['fun2']" />
+<span metal:use-macro="template.macros['fun3']" />
+<span metal:use-macro="template.macros['fun4']" />
+<span metal:use-macro="template.macros['fun5']" />
+<span metal:use-macro="template.macros['fun6']" />
+</body>
+</html>
+'''
+
+
+def test_mako(count):
+    template = PageTemplate(CONTENT_TEMPLATE)
+    base = PageTemplate(BASE_TEMPLATE)
+    page = PageTemplate(PAGE_TEMPLATE)
+
+    table = [xrange(150) for i in xrange(150)]
+    paragraphs = xrange(50)
+    title = 'Hello world!'
+
+    times = []
+    for i in range(count):
+        t0 = time.time()
+        data = template.render(
+            table=table, paragraphs=paragraphs,
+            lorem=LOREM_IPSUM, title=title,
+            img_count=50,
+            base=base,
+            page=page,
+            )
+        t1 = time.time()
+        times.append(t1-t0)
+    return times
+
+if __name__ == "__main__":
+    parser = optparse.OptionParser(
+        usage="%prog [options]",
+        description=("Test the performance of Chameleon templates."))
+    util.add_standard_options_to(parser)
+    (options, args) = parser.parse_args()
+
+    util.run_benchmark(options, options.num_runs, test_mako)
diff --git a/lib3/Chameleon-2.9.2/benchmarks/bm_mako.py b/lib3/Chameleon-2.9.2/benchmarks/bm_mako.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/benchmarks/bm_mako.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python
+
+"""
+Benchmark for test the performance of Mako templates engine.
+Includes:
+    -two template inherences
+    -HTML escaping, XML escaping, URL escaping, whitespace trimming
+    -function defitions and calls
+    -forloops
+"""
+
+__author__ = "virhilo at gmail.com (Lukasz Fidosz)"
+
+# Python imports
+import os
+import sys
+import optparse
+import time
+
+# Local imports
+import util
+
+def relative(*args):
+    return os.path.join(os.path.dirname(os.path.abspath(__file__)), *args)
+
+sys.path.insert(0, relative('..', 'lib'))
+
+# Mako imports
+from mako.template import Template
+from mako.lookup import TemplateLookup
+
+
+LOREM_IPSUM = """Quisque lobortis hendrerit posuere. Curabitur
+aliquet consequat sapien molestie pretium. Nunc adipiscing luc
+tus mi, viverra porttitor lorem vulputate et. Ut at purus sem,
+sed tincidunt ante. Vestibulum ante ipsum primis in faucibus 
+orci luctus et ultrices posuere cubilia Curae; Praesent pulvinar
+sodales justo at congue. Praesent aliquet facilisis nisl a
+molestie. Sed tempus nisl ut augue eleifend tincidunt. Sed a
+lacinia nulla. Cras tortor est, mollis et consequat at,
+vulputate et orci. Nulla sollicitudin"""
+
+BASE_TEMPLATE = """
+<%def name="render_table(table)">
+    <table>
+    % for row in table:
+        <tr>
+        % for col in row:
+            <td>${col|h}</td>
+        % endfor
+        </tr>
+    % endfor
+    </table>
+</%def>
+<%def name="img(src, alt)">
+    <img src="${src|u}" alt="${alt}" />
+</%def>
+<html>
+    <head><title>${title|h,trim}</title></head>
+    <body>
+        ${next.body()}
+    </body>
+<html>
+"""
+
+PAGE_TEMPLATE = """
+<%inherit file="base.mako"/>
+<table>
+    % for row in table:
+        <tr>
+            % for col in row:
+                <td>${col}</td>
+            % endfor
+        </tr>
+    % endfor
+</table>
+% for nr in xrange(img_count):
+    ${parent.img('/foo/bar/baz.png', 'no image :o')}
+% endfor
+${next.body()}
+% for nr in paragraphs:
+    <p>${lorem|x}</p>
+% endfor
+${parent.render_table(table)}
+"""
+
+CONTENT_TEMPLATE = """
+<%inherit file="page.mako"/>
+<%def name="fun1()">
+    <span>fun1</span>
+</%def>
+<%def name="fun2()">
+    <span>fun2</span>
+</%def>
+<%def name="fun3()">
+    <span>foo3</span>
+</%def>
+<%def name="fun4()">
+    <span>foo4</span>
+</%def>
+<%def name="fun5()">
+    <span>foo5</span>
+</%def>
+<%def name="fun6()">
+    <span>foo6</span>
+</%def>
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+Nam laoreet justo in velit faucibus lobortis. Sed dictum sagittis
+volutpat. Sed adipiscing vestibulum consequat. Nullam laoreet, ante
+nec pretium varius, libero arcu porttitor orci, id cursus odio nibh
+nec leo. Vestibulum dapibus pellentesque purus, sed bibendum tortor
+laoreet id. Praesent quis sodales ipsum. Fusce ut ligula sed diam
+pretium sagittis vel at ipsum. Nulla sagittis sem quam, et volutpat
+velit. Fusce dapibus ligula quis lectus ultricies tempor. Pellente</p>
+${fun1()}
+${fun2()}
+${fun3()}
+${fun4()}
+${fun5()}
+${fun6()}
+"""
+
+
+def test_mako(count):
+
+    lookup = TemplateLookup()
+    lookup.put_string('base.mako', BASE_TEMPLATE)
+    lookup.put_string('page.mako', PAGE_TEMPLATE)
+
+    template = Template(CONTENT_TEMPLATE, lookup=lookup)
+    
+    table = [xrange(150) for i in xrange(150)]
+    paragraphs = xrange(50)
+    title = 'Hello world!'
+
+    times = []
+    for i in range(count):
+        t0 = time.time()
+        data = template.render(table=table, paragraphs=paragraphs,
+                               lorem=LOREM_IPSUM, title=title,
+                               img_count=50)
+        t1 = time.time()
+        times.append(t1-t0)
+    return times
+
+if __name__ == "__main__":
+    parser = optparse.OptionParser(
+        usage="%prog [options]",
+        description=("Test the performance of Mako templates."))
+    util.add_standard_options_to(parser)
+    (options, args) = parser.parse_args()
+
+    util.run_benchmark(options, options.num_runs, test_mako)
diff --git a/lib3/Chameleon-2.9.2/benchmarks/util.py b/lib3/Chameleon-2.9.2/benchmarks/util.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/benchmarks/util.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+"""Utility code for benchmark scripts."""
+
+__author__ = "collinwinter at google.com (Collin Winter)"
+
+import math
+import operator
+
+
+def run_benchmark(options, num_runs, bench_func, *args):
+    """Run the given benchmark, print results to stdout.
+
+    Args:
+        options: optparse.Values instance.
+        num_runs: number of times to run the benchmark
+        bench_func: benchmark function. `num_runs, *args` will be passed to this
+            function. This should return a list of floats (benchmark execution
+            times).
+    """
+    if options.profile:
+        import cProfile
+        prof = cProfile.Profile()
+        prof.runcall(bench_func, num_runs, *args)
+        prof.print_stats(sort=options.profile_sort)
+    else:
+        data = bench_func(num_runs, *args)
+        if options.take_geo_mean:
+            product = reduce(operator.mul, data, 1)
+            print math.pow(product, 1.0 / len(data))
+        else:
+            for x in data:
+                print x
+
+
+def add_standard_options_to(parser):
+    """Add a bunch of common command-line flags to an existing OptionParser.
+
+    This function operates on `parser` in-place.
+
+    Args:
+        parser: optparse.OptionParser instance.
+    """
+    parser.add_option("-n", action="store", type="int", default=100,
+                      dest="num_runs", help="Number of times to run the test.")
+    parser.add_option("--profile", action="store_true",
+                      help="Run the benchmark through cProfile.")
+    parser.add_option("--profile_sort", action="store", type="str",
+                      default="time", help="Column to sort cProfile output by.")
+    parser.add_option("--take_geo_mean", action="store_true",
+                      help="Return the geo mean, rather than individual data.")
diff --git a/lib3/Chameleon-2.9.2/distribute_setup.py b/lib3/Chameleon-2.9.2/distribute_setup.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/distribute_setup.py
@@ -0,0 +1,485 @@
+#!python
+"""Bootstrap distribute installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+    from distribute_setup import use_setuptools
+    use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import os
+import sys
+import time
+import fnmatch
+import tempfile
+import tarfile
+from distutils import log
+
+try:
+    from site import USER_SITE
+except ImportError:
+    USER_SITE = None
+
+try:
+    import subprocess
+
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        return subprocess.call(args) == 0
+
+except ImportError:
+    # will be used for python 2.3
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        # quoting arguments if windows
+        if sys.platform == 'win32':
+            def quote(arg):
+                if ' ' in arg:
+                    return '"%s"' % arg
+                return arg
+            args = [quote(arg) for arg in args]
+        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
+
+DEFAULT_VERSION = "0.6.14"
+DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
+SETUPTOOLS_FAKED_VERSION = "0.6c11"
+
+SETUPTOOLS_PKG_INFO = """\
+Metadata-Version: 1.0
+Name: setuptools
+Version: %s
+Summary: xxxx
+Home-page: xxx
+Author: xxx
+Author-email: xxx
+License: xxx
+Description: xxx
+""" % SETUPTOOLS_FAKED_VERSION
+
+
+def _install(tarball):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # installing
+        log.warn('Installing Distribute')
+        if not _python_cmd('setup.py', 'install'):
+            log.warn('Something went wrong during the installation.')
+            log.warn('See the error message above.')
+    finally:
+        os.chdir(old_wd)
+
+
+def _build_egg(egg, tarball, to_dir):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # building an egg
+        log.warn('Building a Distribute egg in %s', to_dir)
+        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
+
+    finally:
+        os.chdir(old_wd)
+    # returning the result
+    log.warn(egg)
+    if not os.path.exists(egg):
+        raise IOError('Could not build the egg.')
+
+
+def _do_download(version, download_base, to_dir, download_delay):
+    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
+                       % (version, sys.version_info[0], sys.version_info[1]))
+    if not os.path.exists(egg):
+        tarball = download_setuptools(version, download_base,
+                                      to_dir, download_delay)
+        _build_egg(egg, tarball, to_dir)
+    sys.path.insert(0, egg)
+    import setuptools
+    setuptools.bootstrap_install_from = egg
+
+
+def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                   to_dir=os.curdir, download_delay=15, no_fake=True):
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    was_imported = 'pkg_resources' in sys.modules or \
+        'setuptools' in sys.modules
+    try:
+        try:
+            import pkg_resources
+            if not hasattr(pkg_resources, '_distribute'):
+                if not no_fake:
+                    _fake_setuptools()
+                raise ImportError
+        except ImportError:
+            return _do_download(version, download_base, to_dir, download_delay)
+        try:
+            pkg_resources.require("distribute>="+version)
+            return
+        except pkg_resources.VersionConflict:
+            e = sys.exc_info()[1]
+            if was_imported:
+                sys.stderr.write(
+                "The required version of distribute (>=%s) is not available,\n"
+                "and can't be installed while this script is running. Please\n"
+                "install a more recent version first, using\n"
+                "'easy_install -U distribute'."
+                "\n\n(Currently using %r)\n" % (version, e.args[0]))
+                sys.exit(2)
+            else:
+                del pkg_resources, sys.modules['pkg_resources']    # reload ok
+                return _do_download(version, download_base, to_dir,
+                                    download_delay)
+        except pkg_resources.DistributionNotFound:
+            return _do_download(version, download_base, to_dir,
+                                download_delay)
+    finally:
+        if not no_fake:
+            _create_fake_setuptools_pkg_info(to_dir)
+
+def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                        to_dir=os.curdir, delay=15):
+    """Download distribute from a specified location and return its filename
+
+    `version` should be a valid distribute version number that is available
+    as an egg for download under the `download_base` URL (which should end
+    with a '/'). `to_dir` is the directory where the egg will be downloaded.
+    `delay` is the number of seconds to pause before an actual download
+    attempt.
+    """
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    try:
+        from urllib.request import urlopen
+    except ImportError:
+        from urllib2 import urlopen
+    tgz_name = "distribute-%s.tar.gz" % version
+    url = download_base + tgz_name
+    saveto = os.path.join(to_dir, tgz_name)
+    src = dst = None
+    if not os.path.exists(saveto):  # Avoid repeated downloads
+        try:
+            log.warn("Downloading %s", url)
+            src = urlopen(url)
+            # Read/write all in one block, so we don't create a corrupt file
+            # if the download is interrupted.
+            data = src.read()
+            dst = open(saveto, "wb")
+            dst.write(data)
+        finally:
+            if src:
+                src.close()
+            if dst:
+                dst.close()
+    return os.path.realpath(saveto)
+
+def _no_sandbox(function):
+    def __no_sandbox(*args, **kw):
+        try:
+            from setuptools.sandbox import DirectorySandbox
+            if not hasattr(DirectorySandbox, '_old'):
+                def violation(*args):
+                    pass
+                DirectorySandbox._old = DirectorySandbox._violation
+                DirectorySandbox._violation = violation
+                patched = True
+            else:
+                patched = False
+        except ImportError:
+            patched = False
+
+        try:
+            return function(*args, **kw)
+        finally:
+            if patched:
+                DirectorySandbox._violation = DirectorySandbox._old
+                del DirectorySandbox._old
+
+    return __no_sandbox
+
+def _patch_file(path, content):
+    """Will backup the file then patch it"""
+    existing_content = open(path).read()
+    if existing_content == content:
+        # already patched
+        log.warn('Already patched.')
+        return False
+    log.warn('Patching...')
+    _rename_path(path)
+    f = open(path, 'w')
+    try:
+        f.write(content)
+    finally:
+        f.close()
+    return True
+
+_patch_file = _no_sandbox(_patch_file)
+
+def _same_content(path, content):
+    return open(path).read() == content
+
+def _rename_path(path):
+    new_name = path + '.OLD.%s' % time.time()
+    log.warn('Renaming %s into %s', path, new_name)
+    os.rename(path, new_name)
+    return new_name
+
+def _remove_flat_installation(placeholder):
+    if not os.path.isdir(placeholder):
+        log.warn('Unkown installation at %s', placeholder)
+        return False
+    found = False
+    for file in os.listdir(placeholder):
+        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
+            found = True
+            break
+    if not found:
+        log.warn('Could not locate setuptools*.egg-info')
+        return
+
+    log.warn('Removing elements out of the way...')
+    pkg_info = os.path.join(placeholder, file)
+    if os.path.isdir(pkg_info):
+        patched = _patch_egg_dir(pkg_info)
+    else:
+        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
+
+    if not patched:
+        log.warn('%s already patched.', pkg_info)
+        return False
+    # now let's move the files out of the way
+    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
+        element = os.path.join(placeholder, element)
+        if os.path.exists(element):
+            _rename_path(element)
+        else:
+            log.warn('Could not find the %s element of the '
+                     'Setuptools distribution', element)
+    return True
+
+_remove_flat_installation = _no_sandbox(_remove_flat_installation)
+
+def _after_install(dist):
+    log.warn('After install bootstrap.')
+    placeholder = dist.get_command_obj('install').install_purelib
+    _create_fake_setuptools_pkg_info(placeholder)
+
+def _create_fake_setuptools_pkg_info(placeholder):
+    if not placeholder or not os.path.exists(placeholder):
+        log.warn('Could not find the install location')
+        return
+    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
+    setuptools_file = 'setuptools-%s-py%s.egg-info' % \
+            (SETUPTOOLS_FAKED_VERSION, pyver)
+    pkg_info = os.path.join(placeholder, setuptools_file)
+    if os.path.exists(pkg_info):
+        log.warn('%s already exists', pkg_info)
+        return
+
+    log.warn('Creating %s', pkg_info)
+    f = open(pkg_info, 'w')
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+
+    pth_file = os.path.join(placeholder, 'setuptools.pth')
+    log.warn('Creating %s', pth_file)
+    f = open(pth_file, 'w')
+    try:
+        f.write(os.path.join(os.curdir, setuptools_file))
+    finally:
+        f.close()
+
+_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
+
+def _patch_egg_dir(path):
+    # let's check if it's already patched
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    if os.path.exists(pkg_info):
+        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
+            log.warn('%s already patched.', pkg_info)
+            return False
+    _rename_path(path)
+    os.mkdir(path)
+    os.mkdir(os.path.join(path, 'EGG-INFO'))
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    f = open(pkg_info, 'w')
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+    return True
+
+_patch_egg_dir = _no_sandbox(_patch_egg_dir)
+
+def _before_install():
+    log.warn('Before install bootstrap.')
+    _fake_setuptools()
+
+
+def _under_prefix(location):
+    if 'install' not in sys.argv:
+        return True
+    args = sys.argv[sys.argv.index('install')+1:]
+    for index, arg in enumerate(args):
+        for option in ('--root', '--prefix'):
+            if arg.startswith('%s=' % option):
+                top_dir = arg.split('root=')[-1]
+                return location.startswith(top_dir)
+            elif arg == option:
+                if len(args) > index:
+                    top_dir = args[index+1]
+                    return location.startswith(top_dir)
+        if arg == '--user' and USER_SITE is not None:
+            return location.startswith(USER_SITE)
+    return True
+
+
+def _fake_setuptools():
+    log.warn('Scanning installed packages')
+    try:
+        import pkg_resources
+    except ImportError:
+        # we're cool
+        log.warn('Setuptools or Distribute does not seem to be installed.')
+        return
+    ws = pkg_resources.working_set
+    try:
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
+                                  replacement=False))
+    except TypeError:
+        # old distribute API
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+
+    if setuptools_dist is None:
+        log.warn('No setuptools distribution found')
+        return
+    # detecting if it was already faked
+    setuptools_location = setuptools_dist.location
+    log.warn('Setuptools installation detected at %s', setuptools_location)
+
+    # if --root or --preix was provided, and if
+    # setuptools is not located in them, we don't patch it
+    if not _under_prefix(setuptools_location):
+        log.warn('Not patching, --root or --prefix is installing Distribute'
+                 ' in another location')
+        return
+
+    # let's see if its an egg
+    if not setuptools_location.endswith('.egg'):
+        log.warn('Non-egg installation')
+        res = _remove_flat_installation(setuptools_location)
+        if not res:
+            return
+    else:
+        log.warn('Egg installation')
+        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
+        if (os.path.exists(pkg_info) and
+            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
+            log.warn('Already patched.')
+            return
+        log.warn('Patching...')
+        # let's create a fake egg replacing setuptools one
+        res = _patch_egg_dir(setuptools_location)
+        if not res:
+            return
+    log.warn('Patched done.')
+    _relaunch()
+
+
+def _relaunch():
+    log.warn('Relaunching...')
+    # we have to relaunch the process
+    # pip marker to avoid a relaunch bug
+    if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
+        sys.argv[0] = 'setup.py'
+    args = [sys.executable] + sys.argv
+    sys.exit(subprocess.call(args))
+
+
+def _extractall(self, path=".", members=None):
+    """Extract all members from the archive to the current working
+       directory and set owner, modification time and permissions on
+       directories afterwards. `path' specifies a different directory
+       to extract to. `members' is optional and must be a subset of the
+       list returned by getmembers().
+    """
+    import copy
+    import operator
+    from tarfile import ExtractError
+    directories = []
+
+    if members is None:
+        members = self
+
+    for tarinfo in members:
+        if tarinfo.isdir():
+            # Extract directories with a safe mode.
+            directories.append(tarinfo)
+            tarinfo = copy.copy(tarinfo)
+            tarinfo.mode = 448 # decimal for oct 0700
+        self.extract(tarinfo, path)
+
+    # Reverse sort directories.
+    if sys.version_info < (2, 4):
+        def sorter(dir1, dir2):
+            return cmp(dir1.name, dir2.name)
+        directories.sort(sorter)
+        directories.reverse()
+    else:
+        directories.sort(key=operator.attrgetter('name'), reverse=True)
+
+    # Set correct owner, mtime and filemode on directories.
+    for tarinfo in directories:
+        dirpath = os.path.join(path, tarinfo.name)
+        try:
+            self.chown(tarinfo, dirpath)
+            self.utime(tarinfo, dirpath)
+            self.chmod(tarinfo, dirpath)
+        except ExtractError:
+            e = sys.exc_info()[1]
+            if self.errorlevel > 1:
+                raise
+            else:
+                self._dbg(1, "tarfile: %s" % e)
+
+
+def main(argv, version=DEFAULT_VERSION):
+    """Install or upgrade setuptools and EasyInstall"""
+    tarball = download_setuptools()
+    _install(tarball)
+
+
+if __name__ == '__main__':
+    main(sys.argv[1:])
diff --git a/lib3/Chameleon-2.9.2/docs/conf.py b/lib3/Chameleon-2.9.2/docs/conf.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/docs/conf.py
@@ -0,0 +1,194 @@
+# -*- coding: utf-8 -*-
+#
+# Chameleon documentation build configuration file, created by
+# sphinx-quickstart on Sun Nov  1 16:08:00 2009.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Chameleon'
+copyright = u'2008-2011 by Malthe Borch and the Repoze Community'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '2.8'
+# The full version, including alpha/beta/rc tags.
+release = '2.8.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+html_title = "Chameleon %s documentation" % version
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bchameleonm,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'chameleondoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'chameleon.tex', u'Chameleon Documentation',
+   u'Malthe Borch et. al', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
diff --git a/lib3/Chameleon-2.9.2/docs/configuration.rst b/lib3/Chameleon-2.9.2/docs/configuration.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/docs/configuration.rst
@@ -0,0 +1,43 @@
+Configuration
+=============
+
+Most settings can be provided as keyword-arguments to the template
+constructor classes.
+
+There are certain settings which are required at environment
+level. Acceptable values are ``"0"``, ``"1"``, or the literals
+``"true"`` or ``"false"`` (case-insensitive).
+
+General usage
+-------------
+
+The following settings are useful in general.
+
+``CHAMELEON_EAGER``
+   Parse and compile templates on instantiation.
+
+``CHAMELEON_CACHE``
+
+   When set to a file system path, the template compiler will write
+   its output to files in this directory and use it as a cache.
+
+   This not only enables you to see the compiler output, but also
+   speeds up startup.
+
+``CHAMELEON_RELOAD``
+   This setting controls the default value of the ``auto_reload``
+   parameter.
+
+Development
+-----------
+
+The following settings are mostly useful during development or
+debugging of the library itself.
+
+``CHAMELEON_DEBUG``
+
+   Enables a set of debugging settings which make it easier to
+   discover and research issues with the engine itself.
+
+   This implicitly enables auto-reload for any template.
+
diff --git a/lib3/Chameleon-2.9.2/docs/index.rst b/lib3/Chameleon-2.9.2/docs/index.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/docs/index.rst
@@ -0,0 +1,217 @@
+Chameleon
+=========
+
+Chameleon is an HTML/XML template engine for `Python
+<http://www.python.org>`_.
+
+It's designed to generate the document output of a web application,
+typically HTML markup or XML.
+
+The language used is *page templates*, originally a `Zope
+<http://www.zope.org>`_ invention [1]_, but available here as a
+:ref:`standalone library <no-dependencies>` that you can use in any
+script or application running Python 2.5 and up (including 3.x and
+`pypy <http://pypy.org>`_). It comes with a set of :ref:`new features
+<new-features>`, too.
+
+The template engine compiles templates into Python byte-code and is optimized
+for speed. For a complex template language, the performance is
+:ref:`very good <fast>`.
+
+  *Found a bug?* Please report issues to the `issue tracker <http://github.com/malthe/chameleon/issues>`_.
+
+  *Need help?* Post to the Pylons `discussion list <http://groups.google.com/group/pylons-discuss/>`_ or join the ``#pyramid`` channel on `Freenode IRC <http://freenode.net/>`_.
+
+Getting the code
+----------------
+
+You can `download <http://pypi.python.org/pypi/Chameleon#downloads>`_ the
+package from the Python package index or install the latest release
+using setuptools or the newer `distribute
+<http://packages.python.org/distribute/>`_ (required for Python 3.x)::
+
+  $ easy_install Chameleon
+
+.. _no-dependencies:
+
+There are no required library dependencies on Python 2.7 and up
+[2]_. On 2.5 and 2.6, the `ordereddict
+<http://pypi.python.org/pypi/ordereddict>`_ and `unittest2
+<http://pypi.python.org/pypi/unittest2>`_ packages are set as
+dependencies.
+
+The project is hosted in a `GitHub repository
+<http://github.com/malthe/chameleon>`_. Code contributions are
+welcome. The easiest way is to use the `pull request
+<http://help.github.com/pull-requests/>`_ interface.
+
+
+Introduction
+------------
+
+The *page templates* language is used within your document structure
+as special element attributes and text markup. Using a set of simple
+language constructs, you control the document flow, element
+repetition, text replacement and translation.
+
+.. note:: If you've used page templates in a Zope environment previously, note that Chameleon uses Python as the default expression language (instead of *path* expressions).
+
+The basic language (known as the *template attribute language* or TAL)
+is simple enough to grasp from an example:
+
+.. code-block:: genshi
+
+  <html>
+    <body>
+      <h1>Hello, ${'world'}!</h1>
+      <table>
+        <tr tal:repeat="row 'apple', 'banana', 'pineapple'">
+          <td tal:repeat="col 'juice', 'muffin', 'pie'">
+             ${row.capitalize()} ${col}
+          </td>
+        </tr>
+      </table>
+    </body>
+  </html>
+
+The ``${...}`` notation is short-hand for text insertion [3]_. The
+Python-expression inside the braces is evaluated and the result
+included in the output. By default, the string is escaped before
+insertion. To avoid this, use the ``structure:`` prefix:
+
+.. code-block:: genshi
+
+  <div>${structure: ...}</div>
+
+Note that if the expression result is an object that implements an
+``__html__()`` method [4]_, this method will be called and the result
+treated as "structure". An example of such an object is the
+``Markup`` class that's included as a utility::
+
+  from chameleon.utils import Markup
+  username = "<tt>%s</tt>" % username
+
+The macro language (known as the *macro expansion language* or METAL)
+provides a means of filling in portions of a generic template.
+
+On the left, the macro template; on the right, a template that loads
+and uses the macro, filling in the "content" slot:
+
+.. code-block:: genshi
+
+  <html xmlns="http://www.w3.org/1999/xhtml">             <metal:main use-macro="load: main.pt">
+    <head>                                                   <p metal:fill-slot="content">${structure: document.body}<p/>
+      <title>Example — ${document.title}</title>    </metal:main>
+    </head>
+    <body>
+      <h1>${document.title}</h1>
+
+      <div id="content">
+        <metal:content define-slot="content" />
+      </div>
+    </body>
+  </html>
+
+In the example, the expression type :ref:`load <load-expression>` is
+used to retrieve a template from the file system using a path relative
+to the calling template.
+
+The METAL system works with TAL such that you can for instance fill in
+a slot that appears in a ``tal:repeat`` loop, or refer to variables
+defined using ``tal:define``.
+
+The third language subset is the translation system (known as the
+*internationalization language* or I18N):
+
+.. code-block:: genshi
+
+  <html i18n:domain="example">
+
+    ...
+
+    <div i18n:translate="">
+       You have <span i18n:name="amount">${round(amount, 2)}</span> dollars in your account.
+    </div>
+
+    ...
+
+  </html>
+
+Each translation message is marked up using ``i18n:translate`` and
+values can be mapped using ``i18n:name``. Attributes are marked for
+translation using ``i18n:attributes``. The template engine generates
+`gettext <http://www.gnu.org/s/gettext/>`_ translation strings from
+the markup::
+
+  "You have ${amount} dollars in your account."
+
+If you use a web framework such as `Pyramid
+<https://docs.pylonsproject.org/docs/pyramid.html>`_, the translation
+system is set up automatically and will negotiate on a *target
+language* based on the HTTP request or other parameter. If not, then
+you need to configure this manually.
+
+Next steps
+----------
+
+This was just an introduction. There are a number of other basic
+statements that you need to know in order to use the language. This is
+all covered in the :ref:`language reference <language-reference>`.
+
+If you're already familiar with the page template language, you can
+skip ahead to the :ref:`getting started <getting-started-with-cpt>`
+section to learn how to use the template engine in your code.
+
+To learn about integration with your favorite web framework see the
+section on :ref:`framework integration <framework-integration>`.
+
+License
+-------
+
+This software is made available under a BSD-like license.
+
+
+Contents
+========
+
+.. toctree::
+   :maxdepth: 2
+
+   library.rst
+   reference.rst
+   integration.rst
+   configuration.rst
+
+Indices and Tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
+Notes
+=====
+
+.. [1] The template language specifications and API for the Page
+       Templates engine are based on Zope Page Templates (see in
+       particular `zope.pagetemplate
+       <http://pypi.python.org/pypi/zope.pagetemplate>`_). However,
+       the Chameleon compiler and Page Templates engine is an entirely
+       new codebase, packaged as a standalone distribution. It does
+       not require a Zope software environment.
+
+.. [2] The translation system in Chameleon is pluggable and based on
+       `gettext <http://www.gnu.org/s/gettext/>`_.
+       There is built-in support for the `zope.i18n
+       <http://pypi.python.org/pypi/zope.i18n>`_ package. If this
+       package is installed, it will be used by default. The
+       `translationstring
+       <http://pypi.python.org/pypi/translationstring>`_ package
+       offers some of the same helper and utility classes, without the
+       Zope application interface.
+
+.. [3] This syntax was taken from `Genshi <http://genshi.edgewall.org/>`_.
+
+.. [4] See the `WebHelpers
+       <https://docs.pylonsproject.org/projects/webhelpers/dev/modules/html/__init__.html>`_
+       library which provide a simple wrapper around this method.
diff --git a/lib3/Chameleon-2.9.2/docs/integration.rst b/lib3/Chameleon-2.9.2/docs/integration.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/docs/integration.rst
@@ -0,0 +1,41 @@
+.. _framework-integration:
+
+Integration
+===========
+
+Integration with Chameleon is available for a number of popular web
+frameworks. The framework will usually provide loading mechanisms and
+translation (internationalization) configuration.
+
+Pyramid
+-------
+
+Chameleon is the default template engine for the `Pyramid
+<http://pylonsproject.org/projects/pyramid/about>`_ framework. See the
+section on `Page Templates
+<http://docs.pylonsproject.org/projects/pyramid/1.1/narr/templates.html#chameleon-zpt-templates>`_ for a complete reference.
+
+Zope 2 / Plone
+--------------
+
+Install the `five.pt <http://pypi.python.org/pypi/five.pt>`_ package
+to replace the reference template engine (globally).
+
+Zope Toolkit (ZTK)
+------------------
+
+Install the `z3c.pt <http://pypi.python.org/pypi/z3c.pt>`_ package for
+applications based on the `Zope Toolkit
+<http://docs.zope.org/zopetoolkit/>`_ (ZTK). Note that you need to
+explicit use the template classes from this package.
+
+Grok
+----
+
+Support for the `Grok <http://grok.zope.org/>`_ framework is available
+in the `grokcore.chameleon
+<http://pypi.python.org/pypi/grokcore.chameleon>`_ package.
+
+This package will setup Grok's policy for templating integration and
+associate the Chameleon template components for the ``.cpt`` template
+filename extension.
diff --git a/lib3/Chameleon-2.9.2/docs/library.rst b/lib3/Chameleon-2.9.2/docs/library.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/docs/library.rst
@@ -0,0 +1,238 @@
+Library Documentation
+=====================
+
+This section documents the package as a Python library. To learn about
+the page template language, consult the :ref:`language reference
+<language-reference>`.
+
+.. _getting-started-with-cpt:
+
+Getting started
+---------------
+
+There are several template constructor classes available, one for each
+of the combinations *text* or *xml*, and *string* or *file*.
+
+The file-based constructor requires an absolute path. To set up a
+templates directory *once*, use the template loader class::
+
+  import os
+
+  path = os.path.dirname(__file__)
+
+  from chameleon import PageTemplateLoader
+  templates = PageTemplateLoader(os.path.join(path, "templates"))
+
+Then, to load a template relative to the provided path, use dictionary
+syntax::
+
+  template = templates['hello.pt']
+
+Alternatively, use the appropriate template class directly. Let's try
+with a string input::
+
+  from chameleon import PageTemplate
+  template = PageTemplate("<div>Hello, ${name}.</div>")
+
+All template instances are callable. Provide variables by keyword
+argument::
+
+  >>> template(name='John')
+  '<div>Hello, John.</div>'
+
+.. _fast:
+
+Performance
+-----------
+
+The template engine compiles (or *translates*) template source code
+into Python byte-code. In simple templates this yields an increase in
+performance of about 7 times in comparison to the reference
+implementation.
+
+In benchmarks for the content management system `Plone
+<http://www.plone.org>`_, switching to Chameleon yields a request to
+response improvement of 20-50%.
+
+Extension
+---------
+
+You can extend the language through the expression engine by writing
+your own expression compiler.
+
+Let's try and write an expression compiler for an expression type that
+will simply uppercase the supplied value. We'll call it ``upper``.
+
+You can write such a compiler as a closure:
+
+.. code-block:: python
+
+   import ast
+
+   def uppercase_expression(string):
+       def compiler(target, engine):
+           uppercased = self.string.uppercase()
+           value = ast.Str(uppercased)
+           return [ast.Assign(targets=[target], value=value)]
+       return compiler
+
+To make it available under a certain prefix, we'll add it to the
+expression types dictionary.
+
+.. code-block:: python
+
+   from chameleon import PageTemplate
+   PageTemplate.expression_types['upper'] = uppercase_expression
+
+Alternatively, you could subclass the template class and set the
+attribute ``expression_types`` to a dictionary that includes your
+expression:
+
+.. code-block:: python
+
+   from chameleon import PageTemplateFile
+   from chameleon.tales import PythonExpr
+
+   class MyPageTemplateFile(PageTemplateFile):
+       expression_types = {
+           'python': PythonExpr,
+           'upper': uppercase_expression
+           }
+
+You can now uppercase strings *natively* in your templates::
+
+  <div tal:content="upper: hello, world" />
+
+It's probably best to stick with a Python expression::
+
+  <div tal:content="'hello, world'.upper()" />
+
+
+.. _whats-new:
+
+Changes between 1.x and 2.x
+---------------------------
+
+This sections describes new features, improvements and changes from
+1.x to 2.x.
+
+New parser
+~~~~~~~~~~
+
+This series features a new, custom-built parser, implemented in pure
+Python. It parses both HTML and XML inputs (the previous parser relied
+on the expat system library and was more strict about its input).
+
+The main benefit of the new parser is that the compiler is now able to
+point to the source location of parse- and compilation errors much
+more accurately. This should be a great aid in debugging these errors.
+
+Compatible output
+~~~~~~~~~~~~~~~~~
+
+The 2.x engine matches the output of the reference implementation more
+closely (usually exactly). There are less differences altogether; for
+instance, the method of escaping TALES expression (usually a
+semicolon) has been changed to match that of the reference
+implementation.
+
+New language features
+~~~~~~~~~~~~~~~~~~~~~
+
+This series also introduces a number of new language features:
+
+1. Support for the ``tal:on-error`` from the reference specification
+   has been added.
+
+2. Two new attributes ``tal:switch`` and ``tal:case`` have been added
+   to make element conditions more flexible.
+
+
+Code improvements
+~~~~~~~~~~~~~~~~~
+
+The template classes have been refactored and simplified allowing
+better reuse of code and more intuitive APIs on the lower levels.
+
+Expression engine
+~~~~~~~~~~~~~~~~~
+
+The expression engine has been redesigned to make it easier to
+understand and extend. The new engine is based on the ``ast`` module
+(available since Python 2.6; backports included for Python 2.5). This
+means that expression compilers now need to return a valid list of AST
+statements that include an assignment to the target node.
+
+Compiler
+~~~~~~~~
+
+The new compiler has been optimized for complex templates. As a
+result, in the benchmark suite included with the package, this
+compiler scores about half of the 1.x series. For most real world
+applications, the engine should still perform as well as the 1.x
+series.
+
+
+API reference
+-------------
+
+This section describes the documented API of the library.
+
+Template classes
+~~~~~~~~~~~~~~~~
+
+Use the ``PageTemplate*`` template classes to define a template from a
+string or file input:
+
+.. automodule:: chameleon
+
+  .. autoclass:: chameleon.PageTemplate
+
+     Note: The remaining classes take the same general configuration
+     arguments.
+
+     .. automethod:: render
+
+  .. autoclass:: chameleon.PageTemplateFile(filename, **config)
+
+  .. autoclass:: chameleon.PageTextTemplate
+
+  .. autoclass:: chameleon.PageTextTemplateFile
+
+Template loader
+~~~~~~~~~~~~~~~
+
+Some systems have framework support for loading templates from
+files. The following loader class is directly compatible with the
+Pylons framework and may be adapted to other frameworks:
+
+.. class:: chameleon.PageTemplateLoader(search_path=None, default_extension=None, **config)
+
+   Load templates from ``search_path`` (must be a string or a list of
+   strings)::
+
+     templates = PageTemplateLoader(path)
+     example = templates['example.pt']
+
+   If ``default_extension`` is provided, this will be added to inputs
+   that do not already have an extension::
+
+     templates = PageTemplateLoader(path, ".pt")
+     example = templates['example']
+
+   Any additional keyword arguments will be passed to the template
+   constructor::
+
+     templates = PageTemplateLoader(path, debug=True, encoding="utf-8")
+
+   .. automethod:: load
+
+Expression engine
+~~~~~~~~~~~~~~~~~
+
+For advanced integration, the compiler module provides support for
+dynamic expression evaluation:
+
+.. automodule:: chameleon.compiler
+
+  .. autoclass:: chameleon.compiler.ExpressionEvaluator
diff --git a/lib3/Chameleon-2.9.2/docs/reference.rst b/lib3/Chameleon-2.9.2/docs/reference.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/docs/reference.rst
@@ -0,0 +1,1695 @@
+:tocdepth: 4
+
+.. _language-reference:
+
+.. highlight:: xml
+
+Language Reference
+==================
+
+The language reference is structured such that it can be read as a
+general introduction to the *page templates* language.
+
+It's split into parts that correspond to each of the main language
+features.
+
+Syntax
+######
+
+You can safely :ref:`skip this section <tal>` if you're familiar with
+how template languages work or just want to learn by example.
+
+An *attribute language* is a programming language designed to render
+documents written in XML or HTML markup.  The input must be a
+well-formed document.  The output from the template is usually
+XML-like but isn't required to be well-formed.
+
+The statements of the language are document tags with special
+attributes, and look like this::
+
+    <p namespace-prefix:command="argument"> ... </p>
+
+In the above example, the attribute
+``namespace-prefix:command="argument"`` is the statement, and the
+entire paragraph tag is the statement's element.  The statement's
+element is the portion of the document on which this statement
+operates.
+
+The namespace prefixes are typically declared once, at the top of a
+template (note that prefix declarations for the template language
+namespaces are omitted from the template output)::
+
+  <html xmlns="http://www.w3.org/1999/xhtml"
+        xmlns:tal="http://xml.zope.org/namespaces/tal"
+        xmlns:metal="http://xml.zope.org/namespaces/metal"
+        xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+    ...
+  </html>
+
+Thankfully, sane namespace prefix defaults are in place to let us skip
+most of the boilerplate::
+
+  <html xmlns="http://www.w3.org/1999/xhtml">
+    <body>
+      <p tal:content="text"> ... </p>
+    </body>
+  </html>
+
+Note how ``tal`` is used without an explicit namespace
+declaration. Chameleon sets up defaults for ``metal`` and ``i18n`` as
+well.
+
+.. note:: Default prefixes are a special feature of Chameleon.
+
+.. _tal:
+
+Basics (TAL)
+############
+
+The *template attribute language* is used to create dynamic XML-like
+content.  It allows elements of a document to be replaced, repeated,
+or omitted.
+
+Statements
+----------
+
+These are the available statements:
+
+==================  ==============
+ Statement           Description
+==================  ==============
+``tal:define``      Define variables.
+``tal:switch``      Defines a switch condition
+``tal:condition``   Include element only if expression is true.
+``tal:repeat``      Repeat an element.
+``tal:case``        Includes element only if expression is equal to parent switch.
+``tal:content``     Substitute the content of an element.
+``tal:replace``     Replace the element with dynamic content.
+``tal:omit-tag``    Omit the element tags, leaving only the inner content.
+``tal:attributes``  Dynamically change or insert element attributes.
+``tal:on-error``    Substitute the content of an element if processing fails.
+==================  ==============
+
+When there is only one TAL statement per element, the order in which
+they are executed is simple.  Starting with the root element, each
+element's statements are executed, then each of its child elements is
+visited, in order, to do the same::
+
+  <html>
+    <meta>
+      <title tal:content="context.title" />
+    </meta>
+    <body>
+      <div tal:condition="items">
+        <p>These are your items:</p>
+        <ul>
+          <li tal:repeat="item items" tal:content="item" />
+        </ul>
+      </div>
+    </body>
+  </html>
+
+Any combination of statements may appear on the same element, except
+that the ``tal:content`` and ``tal:replace`` statements may not be
+used on the same element.
+
+.. note:: The ``tal:case`` and ``tal:switch`` statements are available
+          in Chameleon only.
+
+TAL does not use use the order in which statements are written in the
+tag to determine the order in which they are executed.  When an
+element has multiple statements, they are executed in the order
+printed in the table above.
+
+There is a reasoning behind this ordering.  Because users often want
+to set up variables for use in other statements contained within this
+element or subelements, ``tal:define`` is executed first. Then any
+switch statement. ``tal:condition`` follows, then ``tal:repeat``, then
+``tal:case``. We are now rendering an element; first ``tal:content``
+or ``tal:replace``. Finally, before ``tal:attributes``, we have
+``tal:omit-tag`` (which is implied with ``tal:replace``).
+
+.. note:: *TALES* is used as the expression language for the "stuff in
+   the quotes". The default syntax is simply Python, but
+   other inputs are possible --- see the section on :ref:`expressions
+   <tales>`.
+
+``tal:attributes``
+^^^^^^^^^^^^^^^^^^
+
+Updates or inserts element attributes.
+
+::
+
+  tal:attributes="href request.url"
+
+Syntax
+~~~~~~
+
+``tal:attributes`` syntax::
+
+    argument             ::= attribute_statement [';' attribute_statement]*
+    attribute_statement  ::= attribute_name expression
+    attribute_name       ::= [namespace-prefix ':'] Name
+    namespace-prefix     ::= Name
+
+
+Description
+~~~~~~~~~~~
+
+The ``tal:attributes`` statement replaces the value of an attribute
+(or creates an attribute) with a dynamic value.  The
+value of each expression is converted to a string, if necessary.
+
+.. note:: You can qualify an attribute name with a namespace prefix,
+   for example ``html:table``, if you are generating an XML document
+   with multiple namespaces.
+
+If an attribute expression evaluates to ``None``, the attribute is
+deleted from the statement element (or simply not inserted).
+
+If the expression evaluates to the symbol ``default`` (a symbol which
+is always available when evaluating attributes), its value is defined
+as the default static attribute value. If there is no such default
+value, a return value of ``default`` will drop the attribute.
+
+If you use ``tal:attributes`` on an element with an active
+``tal:replace`` command, the ``tal:attributes`` statement is ignored.
+
+If you use ``tal:attributes`` on an element with a ``tal:repeat``
+statement, the replacement is made on each repetition of the element,
+and the replacement expression is evaluated fresh for each repetition.
+
+.. note:: If you want to include a semicolon (";") in an expression, it
+          must be escaped by doubling it (";;") [1]_.
+
+Examples
+~~~~~~~~
+
+Replacing a link::
+
+    <a href="/sample/link.html"
+       tal:attributes="href context.url()"
+       >
+       ...
+    </a>
+
+Replacing two attributes::
+
+    <textarea rows="80" cols="20"
+              tal:attributes="rows request.rows();cols request.cols()"
+        />
+
+A checkbox input::
+
+    <input type="input" tal:attributes="checked True" />
+
+``tal:condition``
+^^^^^^^^^^^^^^^^^
+
+Conditionally includes or omits an element::
+
+  <div tal:condition="comments">
+    ...
+  </div>
+
+Syntax
+~~~~~~
+
+``tal:condition`` syntax::
+
+    argument ::= expression
+
+Description
+~~~~~~~~~~~
+
+ The ``tal:condition`` statement includes the statement element in the
+ template only if the condition is met, and omits it otherwise.  If
+ its expression evaluates to a *true* value, then normal processing of
+ the element continues, otherwise the statement element is immediately
+ removed from the template.  For these purposes, the value ``nothing``
+ is false, and ``default`` has the same effect as returning a true
+ value.
+
+.. note:: Like Python itself, ZPT considers None, zero, empty strings,
+   empty sequences, empty dictionaries, and instances which return a
+   nonzero value from ``__len__`` or ``__nonzero__`` false; all other
+   values are true, including ``default``.
+
+Examples
+~~~~~~~~
+
+Test a variable before inserting it::
+
+        <p tal:condition="request.message" tal:content="request.message" />
+
+Testing for odd/even in a repeat-loop::
+
+        <div tal:repeat="item range(10)">
+          <p tal:condition="repeat.item.even">Even</p>
+          <p tal:condition="repeat.item.odd">Odd</p>
+        </div>
+
+``tal:content``
+^^^^^^^^^^^^^^^
+
+Replaces the content of an element.
+
+Syntax
+~~~~~~
+
+``tal:content`` syntax::
+
+        argument ::= (['text'] | 'structure') expression
+
+Description
+~~~~~~~~~~~
+
+Rather than replacing an entire element, you can insert text or
+structure in place of its children with the ``tal:content`` statement.
+The statement argument is exactly like that of ``tal:replace``, and is
+interpreted in the same fashion.  If the expression evaluates to
+``nothing``, the statement element is left childless.  If the
+expression evaluates to ``default``, then the element's contents are
+evaluated.
+
+The default replacement behavior is ``text``, which replaces
+angle-brackets and ampersands with their HTML entity equivalents.  The
+``structure`` keyword passes the replacement text through unchanged,
+allowing HTML/XML markup to be inserted.  This can break your page if
+the text contains unanticipated markup (eg.  text submitted via a web
+form), which is the reason that it is not the default.
+
+.. note:: The ``structure`` keyword exists to provide backwards
+          compatibility.  In Chameleon, the ``structure:`` expression
+          type provides the same functionality (also for inline
+          expressions).
+
+
+Examples
+~~~~~~~~
+
+Inserting the user name::
+
+        <p tal:content="user.getUserName()">Fred Farkas</p>
+
+Inserting HTML/XML::
+
+        <p tal:content="structure context.getStory()">
+           Marked <b>up</b> content goes here.
+        </p>
+
+``tal:define``
+^^^^^^^^^^^^^^
+
+Defines local variables.
+
+Syntax
+~~~~~~
+
+``tal:define`` syntax::
+
+    argument ::= define_scope [';' define_scope]*
+    define_scope ::= (['local'] | 'global')
+    define_var define_var ::= variable_name
+    expression variable_name ::= Name
+
+Description
+~~~~~~~~~~~
+
+The ``tal:define`` statement defines variables.  When you define a
+local variable in a statement element, you can use that variable in
+that element and the elements it contains.  If you redefine a variable
+in a contained element, the new definition hides the outer element's
+definition within the inner element.
+
+Note that valid variable names are any Python identifier string
+including underscore, although two or more leading underscores are
+disallowed (used internally by the compiler). Further, names are
+case-sensitive.
+
+Python builtins are always "in scope", but most of them may be
+redefined (such as ``help``). Exceptions are:: ``float``, ``int``,
+``len``, ``long``, ``str``, ``None``, ``True`` and ``False``.
+
+In addition, the following names are reserved: ``econtext``,
+``rcontext``, ``translate``, ``decode`` and ``convert``.
+
+If the expression associated with a variable evaluates to ``nothing``,
+then that variable has the value ``nothing``, and may be used as such
+in further expressions. Likewise, if the expression evaluates to
+``default``, then the variable has the value ``default``, and may be
+used as such in further expressions.
+
+You can define two different kinds of variables: *local* and
+*global*. When you define a local variable in a statement element, you
+can only use that variable in that element and the elements it
+contains. If you redefine a local variable in a contained element, the
+new definition hides the outer element's definition within the inner
+element. When you define a global variables, you can use it in any
+element processed after the defining element. If you redefine a global
+variable, you replace its definition for the rest of the template.
+
+To set the definition scope of a variable, use the keywords ``local``
+or ``global`` in front of the assignment. The default setting is
+``local``; thus, in practice, only the ``global`` keyword is used.
+
+.. note:: If you want to include a semicolon (";") in an expression, it
+          must be escaped by doubling it (";;") [1]_.
+
+Examples
+~~~~~~~~
+
+Defining a variable::
+
+        tal:define="company_name 'Zope Corp, Inc.'"
+
+Defining two variables, where the second depends on the first::
+
+        tal:define="mytitle context.title; tlen len(mytitle)"
+
+
+``tal:switch`` and ``tal:case``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Defines a switch clause.
+
+::
+
+  <ul tal:switch="len(items) % 2">
+    <li tal:case="True">odd</li>
+    <li tal:case="False">even</li>
+  </ul>
+
+Syntax
+~~~~~~
+
+``tal:case`` and ``tal:switch`` syntax::
+
+    argument ::= expression
+
+Description
+~~~~~~~~~~~
+
+The *switch* and *case* construct is a short-hand syntax for
+evaluating a set of expressions against a parent value.
+
+The ``tal:switch`` statement is used to set a new parent value and the
+``tal:case`` statement works like a condition and only allows content
+if the expression matches the value.
+
+Note that if the case expression is the symbol ``default``, it always
+matches the switch.
+
+.. note:: These statements are only available in Chameleon 2.x and not
+          part of the ZPT specification.
+
+Examples
+~~~~~~~~
+
+::
+
+  <ul tal:switch="item.type">
+    <li tal:case="'document'">
+      Document
+    </li>
+    <li tal:case="'folder'">
+      Folder
+    </li>
+  </ul>
+
+Note that any and all cases that match the switch will be included.
+
+
+``tal:omit-tag``
+^^^^^^^^^^^^^^^^
+
+Removes an element, leaving its contents.
+
+Syntax
+~~~~~~
+
+``tal:omit-tag`` syntax::
+
+        argument ::= [ expression ]
+
+Description
+~~~~~~~~~~~
+
+The ``tal:omit-tag`` statement leaves the contents of an element in
+place while omitting the surrounding start and end tags.
+
+If the expression evaluates to a *false* value, then normal processing
+of the element continues and the tags are not omitted.  If the
+expression evaluates to a *true* value, or no expression is provided,
+the statement element is replaced with its contents.
+
+.. note:: Like Python itself, ZPT considers None, zero, empty strings,
+   empty sequences, empty dictionaries, and instances which return a
+   nonzero value from ``__len__`` or ``__nonzero__`` false; all other
+   values are true, including ``default``.
+
+Examples
+~~~~~~~~
+
+Unconditionally omitting a tag::
+
+        <div tal:omit-tag="" comment="This tag will be removed">
+          <i>...but this text will remain.</i>
+        </div>
+
+Conditionally omitting a tag::
+
+        <b tal:omit-tag="not:bold">I may be bold.</b>
+
+The above example will omit the ``b`` tag if the variable ``bold`` is false.
+
+Creating ten paragraph tags, with no enclosing tag::
+
+        <span tal:repeat="n range(10)"
+              tal:omit-tag="">
+          <p tal:content="n">1</p>
+        </span>
+
+.. _tal_repeat:
+
+``tal:repeat``
+^^^^^^^^^^^^^^
+
+Repeats an element.
+
+Syntax
+~~~~~~
+
+``tal:repeat`` syntax::
+
+        argument      ::= variable_name expression
+        variable_name ::= Name
+
+Description
+~~~~~~~~~~~
+
+The ``tal:repeat`` statement replicates a sub-tree of your document
+once for each item in a sequence. The expression should evaluate to a
+sequence. If the sequence is empty, then the statement element is
+deleted, otherwise it is repeated for each value in the sequence.  If
+the expression is ``default``, then the element is left unchanged, and
+no new variables are defined.
+
+The ``variable_name`` is used to define a local variable and a repeat
+variable. For each repetition, the local variable is set to the
+current sequence element, and the repeat variable is set to an
+iteration object.
+
+Repeat variables
+~~~~~~~~~~~~~~~~~
+
+You use repeat variables to access information about the current
+repetition (such as the repeat index).  The repeat variable has the
+same name as the local variable, but is only accessible through the
+built-in variable named ``repeat``.
+
+The following information is available from the repeat variable:
+
+==================  ==============
+ Attribute           Description
+==================  ==============
+``index``           Repetition number, starting from zero.
+``number``          Repetition number, starting from one.
+``even``            True for even-indexed repetitions (0, 2, 4, ...).
+``odd``             True for odd-indexed repetitions (1, 3, 5, ...).
+``start``           True for the starting repetition (index 0).
+``end``             True for the ending, or final, repetition.
+``first``           True for the first item in a group - see note below
+``last``            True for the last item in a group - see note below
+``length``          Length of the sequence, which will be the total number of repetitions.
+``letter``          Repetition number as a lower-case letter: "a" - "z", "aa" - "az", "ba" - "bz", ..., "za" - "zz", "aaa" - "aaz", and so forth.
+``Letter``          Upper-case version of *letter*.
+``roman``           Repetition number as a lower-case roman numeral: "i", "ii", "iii", "iv", "v", etc.
+``Roman``           Upper-case version of *roman*.
+==================  ==============
+
+You can access the contents of the repeat variable using either
+dictionary- or attribute-style access, e.g. ``repeat['item'].start``
+or ``repeat.item.start``.
+
+.. note:: For legacy compatibility, the attributes ``odd``, ``even``, ``number``, ``letter``, ``Letter``, ``roman``, and ``Roman`` are callable (returning ``self``).
+
+Note that ``first`` and ``last`` are intended for use with sorted
+sequences.  They try to divide the sequence into group of items with
+the same value.
+
+Examples
+~~~~~~~~
+
+Iterating over a sequence of strings::    
+
+        <p tal:repeat="txt ('one', 'two', 'three')">
+           <span tal:replace="txt" />
+        </p>
+
+Inserting a sequence of table rows, and using the repeat variable
+to number the rows::
+
+        <table>
+          <tr tal:repeat="item here.cart">
+              <td tal:content="repeat.item.number">1</td>
+              <td tal:content="item.description">Widget</td>
+              <td tal:content="item.price">$1.50</td>
+          </tr>
+        </table>
+
+Nested repeats::
+
+        <table border="1">
+          <tr tal:repeat="row range(10)">
+            <td tal:repeat="column range(10)">
+              <span tal:define="x repeat.row.number; 
+                                y repeat.column.number; 
+                                z x * y"
+                    tal:replace="string:$x * $y = $z">1 * 1 = 1</span>
+            </td>
+          </tr>
+        </table>
+
+Insert objects. Separates groups of objects by type by drawing a rule
+between them::
+
+        <div tal:repeat="object objects">
+          <h2 tal:condition="repeat.object.first.meta_type"
+            tal:content="object.type">Meta Type</h2>
+          <p tal:content="object.id">Object ID</p>
+          <hr tal:condition="object.last.meta_type" />
+        </div>
+
+.. note:: the objects in the above example should already be sorted by
+   type.
+
+``tal:replace``
+^^^^^^^^^^^^^^^
+
+Replaces an element.
+
+Syntax
+~~~~~~
+
+``tal:replace`` syntax::
+
+        argument ::= ['structure'] expression
+
+Description
+~~~~~~~~~~~
+
+
+The ``tal:replace`` statement replaces an element with dynamic
+content.  It replaces the statement element with either text or a
+structure (unescaped markup). The body of the statement is an
+expression with an optional type prefix. The value of the expression
+is converted into an escaped string unless you provide the 'structure' prefix. Escaping consists of converting ``&`` to
+``&amp;``, ``<`` to ``&lt;``, and ``>`` to ``&gt;``.
+
+.. note:: If the inserted object provides an ``__html__`` method, that method is called with the result inserted as structure. This feature is not implemented by ZPT.
+
+If the expression evaluates to ``None``, the element is simply removed.  If the value is ``default``, then the element is left unchanged.
+
+Examples
+~~~~~~~~
+
+Inserting a title::
+
+        <span tal:replace="context.title">Title</span>
+
+Inserting HTML/XML::
+
+        <div tal:replace="structure table" />
+
+.. _tales:
+
+Expressions (TALES)
+###################
+
+The *Template Attribute Language Expression Syntax* (TALES) standard
+describes expressions that supply :ref:`tal` and
+:ref:`metal` with data.  TALES is *one* possible expression
+syntax for these languages, but they are not bound to this definition.
+Similarly, TALES could be used in a context having nothing to do with
+TAL or METAL.
+
+TALES expressions are described below with any delimiter or quote
+markup from higher language layers removed.  Here is the basic
+definition of TALES syntax::
+
+      Expression  ::= [type_prefix ':'] String
+      type_prefix ::= Name
+
+Here are some simple examples::
+
+      1 + 2
+      None
+      string:Hello, ${view.user_name}
+
+The optional *type prefix* determines the semantics and syntax of the
+*expression string* that follows it.  A given implementation of TALES
+can define any number of expression types, with whatever syntax you
+like. It also determines which expression type is indicated by
+omitting the prefix.
+
+Types
+-----
+
+These are the available TALES expression types:
+
+=============  ==============
+ Prefix        Description
+=============  ==============
+``exists``     Evaluate the result inside an exception handler; if one of the exceptions ``AttributeError``, ``LookupError``, ``TypeError``, ``NameError``, or ``KeyError`` is raised during evaluation, the result is ``False``, otherwise ``True``. Note that the original result is discarded in any case.
+``import``     Import a global symbol using dotted notation.
+``load``       Load a template relative to the current template or absolute.
+``not``        Negate the expression result
+``python``     Evaluate a Python expression
+``string``     Format a string
+``structure``  Wraps the expression result as *structure*.
+=============  ==============
+
+.. note:: The default expression type is ``python``.
+
+.. warning:: The Zope reference engine defaults to a ``path``
+             expression type, which is closely tied to the Zope
+             framework. This expression is not implemented in
+             Chameleon (but it's available in a Zope framework
+             compatibility package).
+
+There's a mechanism to allow fallback to alternative expressions, if
+one should fail (raise an exception). The pipe character ('|') is used
+to separate two expressions::
+
+  <div tal:define="page request.GET['page'] | 0">
+
+This mechanism applies only to the ``python`` expression type, and by
+derivation ``string``.
+
+.. _tales_built_in_names:
+
+``python``
+^^^^^^^^^^
+
+Evaluates a Python expression.
+
+Syntax
+~~~~~~
+
+Python expression syntax::
+
+        Any valid Python language expression
+
+Description
+~~~~~~~~~~~
+
+Python expressions are executed natively within the translated
+template source code. There is no built-in security apparatus.
+
+``string``
+^^^^^^^^^^
+
+Syntax
+~~~~~~
+
+String expression syntax::
+
+        string_expression ::= ( plain_string | [ varsub ] )*
+        varsub            ::= ( '$' Variable ) | ( '${ Expression }' )
+        plain_string      ::= ( '$$' | non_dollar )*
+        non_dollar        ::= any character except '$'
+
+Description
+~~~~~~~~~~~
+
+String expressions interpret the expression string as text. If no
+expression string is supplied the resulting string is *empty*. The
+string can contain variable substitutions of the form ``$name`` or
+``${expression}``, where ``name`` is a variable name, and ``expression`` is a TALES-expression. The escaped string value of the expression is inserted into the string.
+
+.. note:: To prevent a ``$`` from being interpreted this
+   way, it must be escaped as ``$$``.
+
+Examples
+~~~~~~~~
+
+Basic string formatting::
+
+    <span tal:replace="string:$this and $that">
+      Spam and Eggs
+    </span>
+
+    <p tal:content="string:${request.form['total']}">
+      total: 12
+    </p>
+
+Including a dollar sign::
+
+    <p tal:content="string:$$$cost">
+      cost: $42.00
+    </p>
+
+.. _import-expression:
+
+``import``
+^^^^^^^^^^
+
+Imports a module global.
+
+.. _structure-expression:
+
+``structure``
+^^^^^^^^^^^^^
+
+Wraps the expression result as *structure*: The replacement text is
+inserted into the document without escaping, allowing HTML/XML markup
+to be inserted.  This can break your page if the text contains
+unanticipated markup (eg.  text submitted via a web form), which is
+the reason that it is not the default.
+
+.. _load-expression:
+
+``load``
+^^^^^^^^
+
+Loads a template instance.
+
+Syntax
+~~~~~~
+
+Load expression syntax::
+
+         Relative or absolute file path
+
+Description
+~~~~~~~~~~~
+
+The template will be loaded using the same template class as the
+calling template.
+
+Examples
+~~~~~~~~
+
+Loading a template and using it as a macro::
+
+  <div tal:define="master load: ../master.pt" metal:use-macro="master" />
+
+
+Built-in names
+--------------
+
+These are the names always available in the TALES expression namespace:
+
+- ``default`` - special value used to specify that existing text or attributes should not be replaced. See the documentation for individual TAL statements for details on how they interpret *default*.
+
+- ``repeat`` - the *repeat* variables; see :ref:`tal_repeat` for more
+  information.
+
+- ``template`` - reference to the template which was first called; this symbol is carried over when using macros.
+
+- ``macros`` - reference to the macros dictionary that corresponds to the current template.
+
+
+.. _metal:
+
+Macros (METAL)
+##############
+
+The *Macro Expansion Template Attribute Language* (METAL) standard is
+a facility for HTML/XML macro preprocessing. It can be used in
+conjunction with or independently of TAL and TALES.
+
+Macros provide a way to define a chunk of presentation in one
+template, and share it in others, so that changes to the macro are
+immediately reflected in all of the places that share it.
+Additionally, macros are always fully expanded, even in a template's
+source text, so that the template appears very similar to its final
+rendering.
+
+A single Page Template can accomodate multiple macros.
+
+Namespace
+---------
+
+The METAL namespace URI and recommended alias are currently defined
+as::
+
+        xmlns:metal="http://xml.zope.org/namespaces/metal"
+
+Just like the TAL namespace URI, this URI is not attached to a web
+page; it's just a unique identifier.  This identifier must be used in
+all templates which use METAL.
+
+Statements
+----------
+
+METAL defines a number of statements:
+
+* ``metal:define-macro`` Define a macro.
+* ``metal:use-macro`` Use a macro.
+* ``metal:extend-macro`` Extend a macro.
+* ``metal:define-slot`` Define a macro customization point.
+* ``metal:fill-slot`` Customize a macro.
+
+Although METAL does not define the syntax of expression non-terminals,
+leaving that up to the implementation, a canonical expression syntax
+for use in METAL arguments is described in TALES Specification.
+
+``define-macro``
+^^^^^^^^^^^^^^^^
+
+Defines a macro.
+
+Syntax
+~~~~~~
+
+``metal:define-macro`` syntax::
+
+        argument ::= Name
+
+Description
+~~~~~~~~~~~
+
+The ``metal:define-macro`` statement defines a macro. The macro is named
+by the statement expression, and is defined as the element and its
+sub-tree.
+
+Examples
+~~~~~~~~
+
+Simple macro definition::
+
+        <p metal:define-macro="copyright">
+          Copyright 2011, <em>Foobar</em> Inc.
+        </p>
+
+``define-slot``
+^^^^^^^^^^^^^^^
+
+Defines a macro customization point.
+
+Syntax
+~~~~~~
+
+``metal:define-slot`` syntax::
+
+        argument ::= Name
+
+Description
+~~~~~~~~~~~
+
+The ``metal:define-slot`` statement defines a macro customization
+point or *slot*. When a macro is used, its slots can be replaced, in
+order to customize the macro. Slot definitions provide default content
+for the slot. You will get the default slot contents if you decide not
+to customize the macro when using it.
+
+The ``metal:define-slot`` statement must be used inside a
+``metal:define-macro`` statement.
+
+Slot names must be unique within a macro.
+
+Examples
+~~~~~~~~
+
+Simple macro with slot::
+
+        <p metal:define-macro="hello">
+          Hello <b metal:define-slot="name">World</b>
+        </p>
+
+This example defines a macro with one slot named ``name``. When you use
+this macro you can customize the ``b`` element by filling the ``name``
+slot.
+
+``fill-slot``
+^^^^^^^^^^^^^
+
+Customize a macro.
+
+Syntax
+~~~~~~
+
+``metal:fill-slot`` syntax::
+
+        argument ::= Name
+
+Description
+~~~~~~~~~~~
+
+The ``metal:fill-slot`` statement customizes a macro by replacing a
+*slot* in the macro with the statement element (and its content).
+
+The ``metal:fill-slot`` statement must be used inside a
+``metal:use-macro`` statement.
+
+Slot names must be unique within a macro.
+
+If the named slot does not exist within the macro, the slot
+contents will be silently dropped.
+
+Examples
+~~~~~~~~
+
+Given this macro::
+
+        <p metal:define-macro="hello">
+          Hello <b metal:define-slot="name">World</b>
+        </p>
+
+You can fill the ``name`` slot like so::
+
+        <p metal:use-macro="container['master.html'].macros.hello">
+          Hello <b metal:fill-slot="name">Kevin Bacon</b>
+        </p>
+
+``use-macro``
+^^^^^^^^^^^^^
+
+Use a macro.
+
+Syntax
+~~~~~~
+
+``metal:use-macro`` syntax::
+
+        argument ::= expression
+
+Description
+~~~~~~~~~~~
+
+The ``metal:use-macro`` statement replaces the statement element with
+a macro. The statement expression describes a macro definition.
+
+.. note:: In Chameleon the expression may point to a template instance; in this case it will be rendered in its entirety.
+
+``extend-macro``
+^^^^^^^^^^^^^^^^
+
+Extends a macro.
+
+Syntax
+~~~~~~
+
+``metal:extend-macro`` syntax::
+
+        argument ::= expression
+
+Description
+~~~~~~~~~~~
+
+To extend an existing macro, choose a name for the macro and add a
+define-macro attribute to a document element with the name as the
+argument. Add an extend-macro attribute to the document element with
+an expression referencing the base macro as the argument. The
+extend-macro must be used in conjunction with define-macro, and must
+not be used with use-macro. The element's subtree is the macro
+body.
+
+Examples
+~~~~~~~~
+
+::
+
+        <div metal:define-macro="page-header"
+             metal:extend-macro="standard_macros['page-header']">
+          <div metal:fill-slot="breadcrumbs">
+            You are here:
+            <div metal:define-slot="breadcrumbs"/>
+          </div>
+        </div>
+
+
+.. _i18n:
+
+Translation (I18N)
+##################
+
+Translation of template contents and attributes is supported via the
+``i18n`` namespace and message objects.
+
+Messages
+--------
+
+The translation machinery defines a message as *any object* which is
+not a string or a number and which does not provide an ``__html__``
+method.
+
+When any such object is inserted into the template, the translate
+function is invoked first to see if it needs translation. The result
+is always coerced to a native string before it's inserted into the
+template.
+
+Translation function
+--------------------
+
+The simplest way to hook into the translation machinery is to provide
+a translation function to the template constructor or at
+render-time. In either case it should be passed as the keyword
+argument ``translate``.
+
+The function has the following signature:
+
+.. code-block:: python
+
+   def translate(msgid, domain=None, mapping=None, context=None, target_language=None, default=None):
+       ...
+
+The result should be a string or ``None``. If another type of object
+is returned, it's automatically coerced into a string.
+
+If `zope.i18n <http://pypi.python.org/pypi/zope.i18n>`_ is available,
+the translation machinery defaults to using its translation
+function. Note that this function requires messages to conform to the
+message class from `zope.i18nmessageid
+<http://pypi.python.org/pypi/zope.i18nmessageid>`_; specifically,
+messages must have attributes ``domain``, ``mapping`` and
+``default``. Example use:
+
+.. code-block:: python
+
+   from zope.i18nmessageid import MessageFactory
+   _ = MessageFactory("food")
+
+   apple = _(u"Apple")
+
+There's currently no further support for other translation frameworks.
+
+Using Zope's translation framework
+-----------------------------------
+
+The translation function from ``zope.i18n`` relies on *translation
+domains* to provide translations.
+
+These are components that are registered for some translation domain
+identifier and which implement a ``translate`` method that translates
+messages for that domain.
+
+.. note:: To register translation domain components, the Zope Component Architecture must be used (see `zope.component <http://pypi.python.org/pypi/zope.component>`_).
+
+The easiest way to configure translation domains is to use the the
+``registerTranslations`` ZCML-directive; this requires the use of the
+`zope.configuration <http://pypi.python.org/pypi/zope.configuration>`_
+package. This will set up translation domains and gettext catalogs
+automatically:
+
+.. code-block:: xml
+
+  <configure xmlns="http://namespaces.zope.org/zope"
+             xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+
+     <i18n:registerTranslations directory="locales" />
+
+  </configure>
+
+The ``./locales`` directory must follow a particular directory
+structure:
+
+.. code-block:: bash
+
+  ./locales/en/LC_MESSAGES
+  ./locales/de/LC_MESSAGES
+  ...
+
+In each of the ``LC_MESSAGES`` directories, one `GNU gettext
+<http://en.wikipedia.org/wiki/GNU_gettext>`_ file in the ``.po``
+format must be present per translation domain:
+
+.. code-block:: po
+
+  # ./locales/de/LC_MESSAGES/food.po
+
+  msgid ""
+  msgstr ""
+  "MIME-Version: 1.0\n"
+  "Content-Type: text/plain; charset=UTF-8\n"
+  "Content-Transfer-Encoding: 8bit\n"
+
+  msgid "Apple"
+  msgstr "Apfel"
+
+It may be necessary to compile the message catalog using the
+``msgfmt`` utility. This will produce a ``.mo`` file.
+
+Translation domains without gettext
+-----------------------------------
+
+The following example demonstrates how to manually set up and
+configure a translation domain for which messages are provided
+directly::
+
+  from zope import component
+  from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
+
+  food = SimpleTranslationDomain("food", {
+      ('de', u'Apple'): u'Apfel',
+      })
+
+  component.provideUtility(food, food.domain)
+
+An example of a custom translation domain class::
+
+  from zope import interface
+
+  class TranslationDomain(object):
+       interface.implements(ITranslationDomain)
+
+       def translate(self, msgid, mapping=None, context=None,
+                    target_language=None, default=None):
+
+           ...
+
+  component.provideUtility(TranslationDomain(), name="custom")
+
+This approach can be used to integrate other translation catalog
+implementations.
+
+.. highlight:: xml
+
+Namespace
+---------
+
+The ``i18n`` namespace URI and recommended prefix are currently
+defined as::
+
+  xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+
+This is not a URL, but merely a unique identifier.  Do not expect a
+browser to resolve it successfully.
+
+Statements
+----------
+
+The allowable ``i18n`` statements are:
+
+- ``i18n:translate``
+- ``i18n:domain``
+- ``i18n:source``
+- ``i18n:target``
+- ``i18n:name``
+- ``i18n:attributes``
+- ``i18n:data``
+
+``i18n:translate``
+^^^^^^^^^^^^^^^^^^
+
+This attribute is used to mark units of text for translation.  If this
+attribute is specified with an empty string as the value, the message
+ID is computed from the content of the element bearing this attribute.
+Otherwise, the value of the element gives the message ID.
+
+``i18n:domain``
+^^^^^^^^^^^^^^^
+
+The ``i18n:domain`` attribute is used to specify the domain to be used
+to get the translation.  If not specified, the translation services
+will use a default domain.  The value of the attribute is used
+directly; it is not a TALES expression.
+
+``i18n:source``
+^^^^^^^^^^^^^^^
+
+The ``i18n:source`` attribute specifies the language of the text to be
+translated.  The default is ``nothing``, which means we don't provide
+this information to the translation services.
+
+
+``i18n:target``
+^^^^^^^^^^^^^^^
+
+The ``i18n:target`` attribute specifies the language of the
+translation we want to get.  If the value is ``default``, the language
+negotiation services will be used to choose the destination language.
+If the value is ``nothing``, no translation will be performed; this
+can be used to suppress translation within a larger translated unit.
+Any other value must be a language code.
+
+The attribute value is a TALES expression; the result of evaluating
+the expression is the language code or one of the reserved values.
+
+.. note:: ``i18n:target`` is primarily used for hints to text
+   extraction tools and translation teams.  If you had some text that
+   should only be translated to e.g. German, then it probably
+   shouldn't be wrapped in an ``i18n:translate`` span.
+
+``i18n:name``
+^^^^^^^^^^^^^
+
+Name the content of the current element for use in interpolation
+within translated content.  This allows a replaceable component in
+content to be re-ordered by translation.  For example::
+
+    <span i18n:translate=''>
+      <span tal:replace='context.name' i18n:name='name' /> was born in
+      <span tal:replace='context.country_of_birth' i18n:name='country' />.
+    </span>
+
+would cause this text to be passed to the translation service::
+
+    "${name} was born in ${country}."
+
+``i18n:attributes``
+^^^^^^^^^^^^^^^^^^^
+
+This attribute will allow us to translate attributes of HTML tags,
+such as the ``alt`` attribute in the ``img`` tag. The
+``i18n:attributes`` attribute specifies a list of attributes to be
+translated with optional message IDs for each; if multiple attribute
+names are given, they must be separated by semicolons.  Message IDs
+used in this context must not include whitespace.
+
+Note that the value of the particular attributes come either from the
+HTML attribute value itself or from the data inserted by
+``tal:attributes``.
+
+If an attibute is to be both computed using ``tal:attributes`` and
+translated, the translation service is passed the result of the TALES
+expression for that attribute.
+
+An example::
+
+    <img src="http://foo.com/logo" alt="Visit us"
+         tal:attributes="alt context.greeting"
+         i18n:attributes="alt"
+         >
+
+In this example, we let ``tal:attributes`` set the value of the ``alt``
+attribute to the text "Stop by for a visit!".  This text will be
+passed to the translation service, which uses the result of language
+negotiation to translate "Stop by for a visit!" into the requested
+language.  The example text in the template, "Visit us", will simply
+be discarded.
+
+Another example, with explicit message IDs::
+
+    <img src="../icons/uparrow.png" alt="Up"
+         i18n:attributes="src up-arrow-icon; alt up-arrow-alttext"
+         >
+
+Here, the message ID ``up-arrow-icon`` will be used to generate the
+link to an icon image file, and the message ID 'up-arrow-alttext' will
+be used for the "alt" text.
+
+``i18n:data``
+^^^^^^^^^^^^^
+
+Since TAL always returns strings, we need a way in ZPT to translate
+objects, one of the most obvious cases being ``datetime`` objects. The
+``data`` attribute will allow us to specify such an object, and
+``i18n:translate`` will provide us with a legal format string for that
+object.  If ``data`` is used, ``i18n:translate`` must be used to give
+an explicit message ID, rather than relying on a message ID computed
+from the content.
+
+Relation with TAL processing
+----------------------------
+
+The attributes defined in the ``i18n`` namespace modify the behavior
+of the TAL interpreter for the ``tal:attributes``, ``tal:content``,
+``tal:repeat``, and ``tal:replace`` attributes, but otherwise do not
+affect TAL processing.
+
+Since these attributes only affect TAL processing by causing
+translations to occur at specific times, using these with a TAL
+processor which does not support the ``i18n`` namespace degrades well;
+the structural expectations for a template which uses the ``i18n``
+support is no different from those for a page which does not.  The
+only difference is that translations will not be performed in a legacy
+processor.
+
+Relation with METAL processing
+-------------------------------
+
+When using translation with METAL macros, the internationalization
+context is considered part of the specific documents that page
+components are retrieved from rather than part of the combined page.
+This makes the internationalization context lexical rather than
+dynamic, making it easier for a site builder to understand the
+behavior of each element with respect to internationalization.
+
+Let's look at an example to see what this means::
+
+    <html i18n:translate='' i18n:domain='EventsCalendar'
+          metal:use-macro="container['master.html'].macros.thismonth">
+
+      <div metal:fill-slot='additional-notes'>
+        <ol tal:condition="context.notes">
+          <li tal:repeat="note context.notes">
+             <tal:block tal:omit-tag=""
+                        tal:condition="note.heading">
+               <strong tal:content="note.heading">
+                 Note heading goes here
+               </strong>
+               <br />
+             </tal:block>
+             <span tal:replace="note/description">
+               Some longer explanation for the note goes here.
+             </span>
+          </li>
+        </ol>
+      </div>
+
+    </html>
+
+And the macro source::
+
+    <html i18n:domain='CalendarService'>
+      <div tal:replace='python:DateTime().Month()'
+           i18n:translate=''>January</div>
+
+      <!-- really hairy TAL code here ;-) -->
+
+      <div define-slot="additional-notes">
+        Place for the application to add additional notes if desired.
+      </div>
+
+    </html>
+
+Note that the macro is using a different domain than the application
+(which it should be).  With lexical scoping, no special markup needs
+to be applied to cause the slot-filler in the application to be part
+of the same domain as the rest of the application's page components.
+If dynamic scoping were used, the internationalization context would
+need to be re-established in the slot-filler.
+
+
+Extracting translatable message
+-------------------------------
+
+Translators use `PO files
+<http://www.gnu.org/software/hello/manual/gettext/PO-Files.html>`_
+when translating messages. To create and update PO files you need to
+do two things: *extract* all messages from python and templates files
+and store them in a ``.pot`` file, and for each language *update* its
+``.po`` file.  Chameleon facilitates this by providing extractors for
+`Babel <http://babel.edgewall.org/>`_.  To use this you need modify
+``setup.py``. For example:
+
+.. code-block:: python
+
+   from setuptools import setup
+
+   setup(name="mypackage",
+         install_requires = [
+               "Babel",
+               ],
+         message_extractors = { "src": [
+               ("**.py",   "chameleon_python", None ),
+               ("**.pt",   "chameleon_xml", None ),
+               ]},
+         )
+
+This tells Babel to scan the ``src`` directory while using the
+``chameleon_python`` extractor for all ``.py`` files and the
+``chameleon_xml`` extractor for all ``.pt`` files.
+
+You can now use Babel to manage your PO files:
+
+.. code-block:: bash
+
+   python setup.py extract_messages --output-file=i18n/mydomain.pot
+   python setup.py update_catalog \
+             -l nl \
+             -i i18n/mydomain.pot \
+             -o i18n/nl/LC_MESSAGES/mydomain.po
+   python setup.py compile_catalog \
+             --directory i18n --locale nl
+
+You can also configure default options in a ``setup.cfg`` file. For example::
+
+   [compile_catalog]
+   domain = mydomain
+   directory = i18n
+   
+   [extract_messages]
+   copyright_holder = Acme Inc.
+   output_file = i18n/mydomain.pot
+   charset = UTF-8
+
+   [init_catalog]
+   domain = mydomain
+   input_file = i18n/mydomain.pot
+   output_dir = i18n
+
+   [update_catalog]
+   domain = mydomain
+   input_file = i18n/mydomain.pot
+   output_dir = i18n
+   previous = true
+
+You can now use the Babel commands directly::
+
+   python setup.py extract_messages
+   python setup.py update_catalog
+   python setup.py compile_catalog
+
+
+${...} operator
+###############
+
+The ``${...}`` notation is short-hand for text insertion. The
+Python-expression inside the braces is evaluated and the result
+included in the output (all inserted text is escaped by default):
+
+.. code-block:: html
+
+  <div id="section-${index + 1}">
+    ${content}
+  </div>
+
+To escape this behavior, prefix the notation with a backslash
+character: ``\${...}``.
+
+Note that if an object implements the ``__html__`` method, the result
+of this method will be inserted as-is (without XML escaping).
+
+Code blocks
+###########
+
+The ``<?python ... ?>`` notation allows you to embed Python code in
+templates:
+
+.. code-block:: html
+
+  <div>
+    <?python numbers = map(str, range(1, 10)) ?>
+    Please input a number from the range ${", ".join(numbers)}.
+  </div>
+
+The scope of name assignments is up to the nearest macro definition,
+or the template, if macros are not used.
+
+Note that code blocks can span multiple line and start on the next
+line of where the processing instruction begins:
+
+.. code-block:: html
+
+  <?python
+    foo = [1, 2, 3]
+  ?>
+
+You can use this to debug templates:
+
+.. code-block:: html
+
+  <div>
+    <?python import pdb; pdb.set_trace() ?>
+  </div>
+
+
+Markup comments
+###############
+
+You can apply the "!" and "?" modifiers to change how comments are
+processed:
+
+Drop
+
+  ``<!--! This comment will be dropped from output -->``
+
+Verbatim
+
+  ``<!--? This comment will be included verbatim -->``
+
+  That is, evaluation of ``${...}`` expressions is disabled if the
+  comment opens with the "?" character.
+
+
+.. _new-features:
+
+Language extensions
+###################
+
+Chameleon extends the *page template* language with a new expression
+types and language features. Some take inspiration from `Genshi
+<http://genshi.edgewall.org/>`_.
+
+    *New expression types*
+
+       The :ref:`structure <structure-expression>` expression wraps an
+       expression result as *structure*::
+
+         <div>${structure: body.text}</div>
+
+       The :ref:`import <import-expression>` expression imports module globals::
+
+         <div tal:define="compile import: re.compile">
+           ...
+         </div>
+
+       The :ref:`load <load-expression>` expression loads templates
+       relative to the current template::
+
+         <div tal:define="compile load: main.pt">
+           ...
+         </div>
+
+    *Tuple unpacking*
+
+       The ``tal:define`` and ``tal:repeat`` statements support tuple
+       unpacking::
+
+          tal:define="(a, b, c) [1, 2, 3]"
+
+       Extended `iterable unpacking
+       <http://www.python.org/dev/peps/pep-3132/>`_ using the asterisk
+       character is not currently supported (even for versions of
+       Python that support it natively).
+
+    *Dictionary lookup as fallback after attribute error*
+
+       If attribute lookup (using the ``obj.<name>`` syntax) raises an
+       ``AttributeError`` exception, a secondary lookup is attempted
+       using dictionary lookup --- ``obj['<name>']``.
+
+       Behind the scenes, this is done by rewriting all
+       attribute-lookups to a custom lookup call:
+
+       .. code-block:: python
+
+            def lookup_attr(obj, key):
+                try:
+                    return getattr(obj, key)
+                except AttributeError as exc:
+                    try:
+                        get = obj.__getitem__
+                    except AttributeError:
+                        raise exc
+                    try:
+                        return get(key)
+                    except KeyError:
+                        raise exc
+
+    *Inline string substitution*
+
+       In element attributes and in the text or tail of an element,
+       string expression interpolation is available using the
+       ``${...}`` syntax::
+
+          <span class="content-${item_type}">
+             ${title or item_id}
+          </span>
+
+    *Code blocks*
+
+        Using ``<?python ... ?>`` notation, you can embed Python
+        statements in your templates:
+
+        .. code-block:: html
+
+          <div>
+            <?python numbers = map(str, range(1, 10)) ?>
+            Please input a number from the range ${", ".join(numbers)}.
+          </div>
+
+    *Literal content*
+
+       While the ``tal:content`` and ``tal:repeat`` attributes both
+       support the ``structure`` keyword which inserts the content as
+       a literal (without XML-escape), an object may also provide an
+       ``__html__`` method to the same effect.
+
+       The result of the method will be inserted as *structure*.
+
+       This is particularly useful for content which is substituted
+       using the expression operator: ``"${...}"`` since the
+       ``structure`` keyword is not allowed here.
+
+    *Switch statement*
+
+       Two new attributes have been added: ``tal:switch`` and
+       ``tal:case``. A case attribute works like a condition and only
+       allows content if the value matches that of the nearest parent
+       switch value.
+
+
+Incompatibilities and differences
+#################################
+
+There are a number of incompatibilities and differences between the
+Chameleon language implementation and the Zope reference
+implementation (ZPT):
+
+    *Default expression*
+
+       The default expression type is Python.
+
+    *Template arguments*
+
+      Arguments passed by keyword to the render- or call method are
+      inserted directly into the template execution namespace. This is
+      different from ZPT where these are only available through the
+      ``options`` dictionary.
+
+      Zope::
+
+        <div tal:content="options/title" />
+
+      Chameleon::
+
+        <div tal:content="title" />
+
+    *Special symbols*
+
+      The ``CONTEXTS`` symbol is not available.
+
+The `z3c.pt <http://pypi.python.org/pypi/z3c.pt>`_ package works as a
+compatibility layer. The template classes in this package provide a
+implementation which is fully compatible with ZPT.
+
+Notes
+#####
+
+.. [1] This has been changed in 2.x. Previously, it was up to the
+       expression engine to parse the expression values including any
+       semicolons and since for instance Python-expressions can never
+       end in a semicolon, it was possible to clearly distinguish
+       between the different uses of the symbol, e.g.
+
+       ::
+
+         tal:define="text 'Hello world; goodbye world'"
+
+       The semicolon appearing in the definition above is part of the
+       Python-expression simply because it makes the expression
+       valid. Meanwhile:
+
+       ::
+
+         tal:define="text1 'Hello world'; text2 'goodbye world'"
+
+       The semicolon here must denote a second variable definition
+       because there is no valid Python-expression that includes it.
+
+       While this behavior works well in practice, it is incompatible
+       with the reference specification, and also blurs the interface
+       between the compiler and the expression engine. In 2.x we
+       therefore have to escape the semicolon by doubling it (as
+       defined by the specification):
+
+       ::
+
+         tal:define="text 'Hello world;; goodbye world'"
+
diff --git a/lib3/Chameleon-2.9.2/setup.cfg b/lib3/Chameleon-2.9.2/setup.cfg
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/setup.cfg
@@ -0,0 +1,14 @@
+[easy_install]
+zip_ok = false
+
+[nosetests]
+match = ^test
+nocapture = 1
+cover-package = tree.codegen, tree.lexer, tree.parser, tree.nodes, tree.translation, tree.language, tree.tales, tree.expressions
+cover-erase = 1
+
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/lib3/Chameleon-2.9.2/setup.py b/lib3/Chameleon-2.9.2/setup.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/setup.py
@@ -0,0 +1,90 @@
+__version__ = '2.9.2'
+
+import os
+import sys
+
+try:
+    from distribute_setup import use_setuptools
+    use_setuptools()
+except:  # doesn't work under tox/pip
+    pass
+
+from setuptools import setup, find_packages
+from setuptools.command.test import test
+
+here = os.path.abspath(os.path.dirname(__file__))
+try:
+    README = open(os.path.join(here, 'README.rst')).read()
+    CHANGES = open(os.path.join(here, 'CHANGES.rst')).read()
+except:  # doesn't work under tox/pip
+    README = ''
+    CHANGES = ''
+
+install_requires = []
+
+version = sys.version_info[:3]
+if version < (2, 7, 0):
+    install_requires.append("ordereddict")
+    install_requires.append("unittest2")
+
+
+class Benchmark(test):
+    description = "Run benchmarks"
+    user_options = []
+    test_suite = None
+
+    def initialize_options(self):
+        """init options"""
+        pass
+
+    def finalize_options(self):
+        """finalize options"""
+
+        self.distribution.tests_require = [
+            'zope.pagetemplate',
+            'zope.component',
+            'zope.i18n',
+            'zope.testing']
+
+    def run(self):
+        test.run(self)
+        self.with_project_on_sys_path(self.run_benchmark)
+
+    def run_benchmark(self):
+        from chameleon import benchmark
+        print("running benchmark...")
+
+        benchmark.start()
+
+setup(
+    name="Chameleon",
+    version=__version__,
+    description="Fast HTML/XML Template Compiler.",
+    long_description="\n\n".join((README, CHANGES)),
+    classifiers=[
+       "Development Status :: 5 - Production/Stable",
+       "Intended Audience :: Developers",
+       "Programming Language :: Python",
+       "Programming Language :: Python :: 2",
+       "Programming Language :: Python :: 3",
+       "Programming Language :: Python :: 2.5",
+       "Programming Language :: Python :: 2.6",
+       "Programming Language :: Python :: 2.7",
+       "Programming Language :: Python :: 3.1",
+       "Programming Language :: Python :: 3.2",
+      ],
+    author="Malthe Borch",
+    author_email="mborch at gmail.com",
+    url="http://www.pagetemplates.org/",
+    license='BSD-like (http://repoze.org/license.html)',
+    packages=find_packages('src'),
+    package_dir = {'': 'src'},
+    include_package_data=True,
+    install_requires=install_requires,
+    zip_safe=False,
+    test_suite="chameleon.tests",
+    cmdclass={
+        'benchmark': Benchmark,
+        }
+    )
+
diff --git a/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/PKG-INFO b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/PKG-INFO
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/PKG-INFO
@@ -0,0 +1,1122 @@
+Metadata-Version: 1.1
+Name: Chameleon
+Version: 2.9.2
+Summary: Fast HTML/XML Template Compiler.
+Home-page: http://www.pagetemplates.org/
+Author: Malthe Borch
+Author-email: mborch at gmail.com
+License: BSD-like (http://repoze.org/license.html)
+Description: Overview
+        ========
+        
+        Chameleon is an HTML/XML template engine for `Python
+        <http://www.python.org>`_. It uses the *page templates* language.
+        
+        You can use it in any Python web application with just about any
+        version of Python (2.5 and up, including 3.x and `pypy
+        <http://pypy.org>`_).
+        
+        Visit the `website <http://pagetemplates.org>`_ for more information
+        or the `documentation <http://pagetemplates.org/docs/latest/>`_.
+        
+        License and Copyright
+        ---------------------
+        
+        This software is made available as-is under a BSD-like license [1]_
+        (see included copyright notice).
+        
+        
+        Notes
+        -----
+        
+        .. [1] This software is licensed under the `Repoze
+               <http://repoze.org/license.html>`_ license.
+        
+        
+        Changes
+        =======
+        
+        2.9.2 (2012-06-06)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed a PyPy incompatibility.
+        
+        - Fixed issue #109 which caused testing failures on some platforms.
+        
+        2.9.1 (2012-06-01)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed issue #103. The ``tal:on-error`` statement now always adds an
+          explicit end-tag to the element, even with a substitution content of
+          nothing.
+        
+        - Fixed issue #113. The ``tal:on-error`` statement now works correctly
+          also for dynamic attributes. That is, the fallback tag now includes
+          only static attributes.
+        
+        - Fixed name error which prevented the benchmark from running
+          correctly.
+        
+        Compatibility:
+        
+        - Fixed deprecation warning on Python 3 for zope interface implements
+          declaration. This fixes issue #116.
+        
+        2.9.0 (2012-05-31)
+        ------------------
+        
+        Features:
+        
+        - The translation function now gets the ``econtext`` argument as the
+          value for ``context``. Note that historically, this was usually an
+          HTTP request which might provide language negotiation data through a
+          dictionary interface.
+          [alvinyue]
+        
+        Bugfixes:
+        
+        - Fixed import alias issue which would lead to a syntax error in
+          generated Python code. Fixes issue #114.
+        
+        2.8.5 (2012-05-02)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed minor installation issues on Python 2.5 and 3.
+          [ppaez]
+        
+        - Ensure output is unicode even when trivial (an empty string).
+        
+        2.8.4 (2012-04-18)
+        ------------------
+        
+        Features:
+        
+        - In exception output, long filenames are now truncated to 60
+          characters of output, preventing line wrap which makes it difficult
+          to scan the exception output.
+        
+        Bugfixes:
+        
+        - Include filename and location in exception output for exceptions
+          raised during compilation.
+        
+        - If a trivial translation substitution variable is given (i.e. an
+          empty string), simply ignore it. This fixes issue #106.
+        
+        2.8.3 (2012-04-16)
+        ------------------
+        
+        Features:
+        
+        - Log template source on debug-level before cooking.
+        
+        - The `target_language` argument, if given, is now available as a
+          variable in templates.
+        
+        2.8.2 (2012-03-30)
+        ------------------
+        
+        Features:
+        
+        - Temporary caches used in debug mode are cleaned up eagerly, rather
+          than waiting for process termination.
+          [mitchellrj]
+        
+        Bugfixes:
+        
+        - The `index`, `start` and `end` methods on the TAL repeat object are
+          now callable. This fixes an incompatibility with ZPT.
+        
+        - The loader now correctly handles absolute paths on Windows.
+          [rdale]
+        
+        2.8.1 (2012-03-29)
+        ------------------
+        
+        Features:
+        
+        - The exception formatter now lists errors in 'wrapping order'. This
+          means that the innermost, and presumably most relevant exception is
+          shown last.
+        
+        Bugfixes:
+        
+        - The exception formatter now correctly recognizes nested errors and
+          does not rewrap the dynamically generated exception class.
+        
+        - The exception formatter now correctly sets the ``__module__``
+          attribute to that of the original exception class.
+        
+        2.8.0 (2012-02-29)
+        ------------------
+        
+        Features:
+        
+        - Added support for code blocks using the `<?python ... ?>` processing
+          instruction syntax.
+        
+          The scope is name assignments is up until the nearest macro
+          definition, or the template itself if macros are not used.
+        
+        Bugfixes:
+        
+        - Fall back to the exception class' ``__new__`` method to safely
+          create an exception object that is not implemented in Python.
+        
+        - The exception formatter now keeps track of already formatted
+          exceptions, and ignores them from further output.
+        
+        2.7.4 (2012-02-27)
+        ------------------
+        
+        - The error handler now invokes the ``__init__`` method of
+          ``BaseException`` instead of the possibly overriden method (which
+          may take required arguments). This fixes issue #97.
+          [j23d, malthe]
+        
+        2.7.3 (2012-01-16)
+        ------------------
+        
+        Bugfixes:
+        
+        - The trim whitespace option now correctly trims actual whitespace to
+          a single character, appearing either to the left or to the right of
+          an element prefix or suffix string.
+        
+        2.7.2 (2012-01-08)
+        ------------------
+        
+        Features:
+        
+        - Added option ``trim_attribute_space`` that decides whether attribute
+          whitespace is stripped (at most down to a single space). This option
+          exists to provide compatibility with the reference
+          implementation. Fixes issue #85.
+        
+        Bugfixes:
+        
+        - Ignore unhashable builtins when generating a reverse builtin
+          map to quickly look up a builtin value.
+          [malthe]
+        
+        - Apply translation mapping even when a translation function is not
+          available. This fixes issue #83.
+          [malthe]
+        
+        - Fixed issue #80. The translation domain for a slot is defined by the
+          source document, i.e. the template providing the content for a slot
+          whether it be the default or provided through ``metal:fill-slot``.
+          [jcbrand]
+        
+        - In certain circumstances, a Unicode non-breaking space character would cause
+          a define clause to fail to parse.
+        
+        2.7.1 (2011-12-29)
+        ------------------
+        
+        Features:
+        
+        - Enable expression interpolation in CDATA.
+        
+        - The page template class now implements dictionary access to macros::
+        
+             template[name]
+        
+          This is a short-hand for::
+        
+             template.macros[name]
+        
+        Bugfixes:
+        
+        - An invalid define clause would be silently ignored; we now raise a
+          language error exception. This fixes issue #79.
+        
+        - Fixed regression where ``${...}`` interpolation expressions could
+          not span multiple lines. This fixes issue #77.
+        
+        2.7.0 (2011-12-13)
+        ------------------
+        
+        Features:
+        
+        - The ``load:`` expression now derives from the string expression such
+          that the ``${...}`` operator can be used for expression
+          interpolation.
+        
+        - The ``load:`` expression now accepts asset specs; these are resolved
+          by the ``pkg_resources.resource_filename`` function::
+        
+            <package_name>:<path>
+        
+          An example from the test suite::
+        
+            chameleon:tests/inputs/hello_world.pt
+        
+        Bugfixes:
+        
+        - If an attribute name for translation was not a valid Python
+          identifier, the compiler would generate invalid code. This has been
+          fixed, and the compiler now also throws an exception if an attribute
+          specification contains a comma. (Note that the only valid separator
+          character is the semicolon, when specifying attributes for
+          translation via the ``i18n:translate`` statement). This addresses
+          issue #76.
+        
+        2.6.2 (2011-12-08)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed issue where ``tal:on-error`` would not respect
+          ``tal:omit-tag`` or namespace elements which are omitted by default
+          (such as ``<tal:block />``).
+        
+        - Fixed issue where ``macros`` attribute would not be available on
+          file-based templates due to incorrect initialization.
+        
+        - The ``TryExcept`` and ``TryFinally`` AST nodes are not available on
+          Python 3.3. These have been aliased to ``Try``. This fixes issue
+          #75.
+        
+        Features:
+        
+        - The TAL repeat item now makes a security declaration that grants
+          access to unprotected subobjects on the Zope 2 platform::
+        
+            __allow_access_to_unprotected_subobjects__ = True
+        
+          This is required for legacy compatibility and does not affect other
+          environments.
+        
+        - The template object now has a method ``write(body)`` which
+          explicitly decodes and cooks a string input.
+        
+        - Added configuration option ``loader_class`` which sets the class
+          used to create the template loader object.
+        
+          The class (essentially a callable) is created at template
+          construction time.
+        
+        2.6.1 (2011-11-30)
+        ------------------
+        
+        Bugfixes:
+        
+        - Decode HTML entities in expression interpolation strings. This fixes
+          issue #74.
+        
+        - Allow ``xml`` and ``xmlns`` attributes on TAL, I18N and METAL
+          namespace elements. This fixes issue #73.
+        
+        2.6.0 (2011-11-24)
+        ------------------
+        
+        Features:
+        
+        - Added support for implicit translation:
+        
+          The ``implicit_i18n_translate`` option enables implicit translation
+          of text. The ``implicit_i18n_attributes`` enables implicit
+          translation of attributes. The latter must be a set and for an
+          attribute to be implicitly translated, its lowercase string value
+          must be included in the set.
+        
+        - Added option ``strict`` (enabled by default) which decides whether
+          expressions are required to be valid at compile time. That is, if
+          not set, an exception is only raised for an invalid expression at
+          evaluation time.
+        
+        - An expression error now results in an exception only if the
+          expression is attempted evaluated during a rendering.
+        
+        - Added a configuration option ``prepend_relative_search_path`` which
+          decides whether the path relative to a file-based template is
+          prepended to the load search path. The default is ``True``.
+        
+        - Added a configuration option ``search_path`` to the file-based
+          template class, which adds additional paths to the template load
+          instance bound to the ``load:`` expression. The option takes a
+          string path or an iterable yielding string paths. The default value
+          is the empty set.
+        
+        Bugfixes:
+        
+        - Exception instances now support pickle/unpickle.
+        
+        - An attributes in i18n:attributes no longer needs to match an
+          existing or dynamic attribute in order to appear in the
+          element. This fixes issue #66.
+        
+        2.5.3 (2011-10-23)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue where a nested macro slot definition would fail even
+          though there existed a parent macro definition. This fixes issue
+          #69.
+        
+        2.5.2 (2011-10-12)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue where technically invalid input would result in a
+          compiler error.
+        
+        Features:
+        
+        - The markup class now inherits from the unicode string type such that
+          it's compatible with the string interface.
+        
+        2.5.1 (2011-09-29)
+        ------------------
+        
+        Bugfixes:
+        
+        - The symbol names "convert", "decode" and "translate" are now no
+          longer set as read-only *compiler internals*. This fixes issue #65.
+        
+        - Fixed an issue where a macro extension chain nested two levels (a
+          template uses a macro that extends a macro) would lose the middle
+          slot definitions if slots were defined nested.
+        
+          The compiler now throws an error if a nested slot definition is used
+          outside a macro extension context.
+        
+        2.5.0 (2011-09-23)
+        ------------------
+        
+        Features:
+        
+        - An expression type ``structure:`` is now available which wraps the
+          expression result as *structure* such that it is not escaped on
+          insertion, e.g.::
+        
+            <div id="content">
+               ${structure: context.body}
+            </div>
+        
+          This also means that the ``structure`` keyword for ``tal:content``
+          and ``tal:replace`` now has an alternative spelling via the
+          expression type ``structure:``.
+        
+        - The string-based template constructor now accepts encoded input.
+        
+        2.4.6 (2011-09-23)
+        ------------------
+        
+        Bugfixes:
+        
+        - The ``tal:on-error`` statement should catch all exceptions.
+        
+        - Fixed issue that would prevent escaping of interpolation expression
+          values appearing in text.
+        
+        2.4.5 (2011-09-21)
+        ------------------
+        
+        Bugfixes:
+        
+        - The ``tal:on-error`` handler should have a ``error`` variable
+          defined that has the value of the exception thrown.
+        
+        - The ``tal:on-error`` statement is a substitution statement and
+          should support the "text" and "structure" insertion methods.
+        
+        2.4.4 (2011-09-15)
+        ------------------
+        
+        Bugfixes:
+        
+        - An encoding specified in the XML document preamble is now read and
+          used to decode the template input to unicode. This fixes issue #55.
+        
+        - Encoded expression input on Python 3 is now correctly
+          decoded. Previously, the string representation output would be
+          included instead of an actually decoded string.
+        
+        - Expression result conversion steps are now correctly included in
+          error handling such that the exception output points to the
+          expression location.
+        
+        2.4.3 (2011-09-13)
+        ------------------
+        
+        Features:
+        
+        - When an encoding is provided, pass the 'ignore' flag to avoid
+          decoding issues with bad input.
+        
+        Bugfixes:
+        
+        - Fixed pypy compatibility issue (introduced in previous release).
+        
+        2.4.2 (2011-09-13)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue in the compiler where an internal variable (such as a
+          translation default value) would be cached, resulting in variable
+          scope corruption (see issue #49).
+        
+        2.4.1 (2011-09-08)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue where a default value for an attribute would
+          sometimes spill over into another attribute.
+        
+        - Fixed issue where the use of the ``default`` name in an attribute
+          interpolation expression would print the attribute value. This is
+          unexpected, because it's an expression, not a static text suitable
+          for output. An attribute value of ``default`` now correctly drops
+          the attribute.
+        
+        2.4.0 (2011-08-22)
+        ------------------
+        
+        Features:
+        
+        - Added an option ``boolean_attributes`` to evaluate and render a
+          provided set of attributes using a boolean logic: if the attribute
+          is a true value, the value will be the attribute name, otherwise the
+          attribute is dropped.
+        
+          In the reference implementation, the following attributes are
+          configured as boolean values when the template is rendered in
+          HTML-mode::
+        
+              "compact", "nowrap", "ismap", "declare", "noshade",
+              "checked", "disabled", "readonly", "multiple", "selected",
+              "noresize", "defer"
+        
+          Note that in Chameleon, these attributes must be manually provided.
+        
+        Bugfixes:
+        
+        - The carriage return character (used on Windows platforms) would
+          incorrectly be included in Python comments.
+        
+          It is now replaced with a line break.
+        
+          This fixes issue #44.
+        
+        2.3.8 (2011-08-19)
+        ------------------
+        
+        - Fixed import error that affected Python 2.5 only.
+        
+        2.3.7 (2011-08-19)
+        ------------------
+        
+        Features:
+        
+        - Added an option ``literal_false`` that disables the default behavior
+          of dropping an attribute for a value of ``False`` (in addition to
+          ``None``). This modified behavior is the behavior exhibited in
+          reference implementation.
+        
+        Bugfixes:
+        
+        - Undo attribute special HTML attribute behavior (see previous
+          release).
+        
+          This turned out not to be a compatible behavior; rather, boolean
+          values should simply be coerced to a string.
+        
+          Meanwhile, the reference implementation does support an HTML mode in
+          which the special attribute behavior is exhibited.
+        
+          We do not currently support this mode.
+        
+        2.3.6 (2011-08-18)
+        ------------------
+        
+        Features:
+        
+        - Certain HTML attribute names now have a special behavior for a
+          attribute value of ``True`` (or ``default`` if no default is
+          defined). For these attributes, this return value will result in the
+          name being printed as the value::
+        
+            <input type="input" tal:attributes="checked True" />
+        
+          will be rendered as::
+        
+            <input type="input" checked="checked" />
+        
+          This behavior is compatible with the reference implementation.
+        
+        2.3.5 (2011-08-18)
+        ------------------
+        
+        Features:
+        
+        - Added support for the set operator (``{item, item, ...}``).
+        
+        Bugfixes:
+        
+        - If macro is defined on the same element as a translation name, this
+          no longer results in a "translation name not allowed outside
+          translation" error. This fixes issue #43.
+        
+        - Attribute fallback to dictionary lookup now works on multiple items
+          (e.g. ``d1.d2.d2``). This fixes issue #42.
+        
+        2.3.4 (2011-08-16)
+        ------------------
+        
+        Features:
+        
+        - When inserting content in either attributes or text, a value of
+          ``True`` (like ``False`` and ``None``) will result in no
+          action.
+        
+        - Use statically assigned variables for ``"attrs"`` and
+          ``"default"``. This change yields a performance improvement of
+          15-20%.
+        
+        - The template loader class now accepts an optional argument
+          ``default_extension`` which accepts a filename extension which will
+          be appended to the filename if there's not already an extension.
+        
+        Bugfixes:
+        
+        - The default symbol is now ``True`` for an attribute if the attribute
+          default is not provided. Note that the result is that the attribute
+          is dropped. This fixes issue #41.
+        
+        - Fixed an issue where assignment to a variable ``"type"`` would
+          fail. This fixes issue #40.
+        
+        - Fixed an issue where an (unsuccesful) assignment for a repeat loop
+          to a compiler internal name would not result in an error.
+        
+        - If the translation function returns the identical object, manually
+          coerce it to string. This fixes a compatibility issue with
+          translation functions which do not convert non-string objects to a
+          string value, but simply return them unchanged.
+        
+        2.3.3 (2011-08-15)
+        ------------------
+        
+        Features:
+        
+        - The ``load:`` expression now passes the initial keyword arguments to
+          its template loader (e.g. ``auto_reload`` and ``encoding``).
+        
+        - In the exception output, string variable values are now limited to a
+          limited output of characters, single line only.
+        
+        Bugfixes:
+        
+        - Fixed horizontal alignment of exception location info
+          (i.e. 'String:', 'Filename:' and 'Location:') such that they match
+          the template exception formatter.
+        
+        2.3.2 (2011-08-11)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed issue where i18n:domain would not be inherited through macros
+          and slots. This fixes issue #37.
+        
+        2.3.1 (2011-08-11)
+        ------------------
+        
+        Features:
+        
+        - The ``Builtin`` node type may now be used to represent any Python
+          local or global name. This allows expression compilers to refer to
+          e.g. ``get`` or ``getitem``, or to explicit require a builtin object
+          such as one from the ``extra_builtins`` dictionary.
+        
+        Bugfixes:
+        
+        - Builtins which are not explicitly disallowed may now be redefined
+          and used as variables (e.g. ``nothing``).
+        
+        - Fixed compiler issue with circular node annotation loop.
+        
+        2.3 (2011-08-10)
+        ----------------
+        
+        Features:
+        
+        - Added support for the following syntax to disable inline evaluation
+          in a comment:
+        
+            <!--? comment appears verbatim (no ${...} evaluation) -->
+        
+          Note that the initial question mark character (?) will be omitted
+          from output.
+        
+        - The parser now accepts '<' and '>' in attributes. Note that this is
+          invalid markup. Previously, the '<' would not be accepted as a valid
+          attribute value, but this would result in an 'unexpected end tag'
+          error elsewhere. This fixes issue #38.
+        
+        - The expression compiler now provides methods ``assign_text`` and
+          ``assign_value`` such that a template engine might configure this
+          value conversion to support e.g. encoded strings.
+        
+          Note that currently, the only client for the ``assign_text`` method
+          is the string expression type.
+        
+        - Enable template loader for string-based template classes. Note that
+          the ``filename`` keyword argument may be provided on initialization
+          to identify the template source by filename. This fixes issue #36.
+        
+        - Added ``extra_builtins`` option to the page template class. These
+          builtins are added to the default builtins dictionary at cook time
+          and may be provided at initialization using the ``extra_builtins``
+          keyword argument.
+        
+        Bugfixes:
+        
+        - If a translation domain is set for a fill slot, use this setting
+          instead of the macro template domain.
+        
+        - The Python expression compiler now correctly decodes HTML entities
+          ``'gt'`` and ``'lt'``. This fixes issue #32.
+        
+        - The string expression compiler now correctly handles encoded text
+          (when support for encoded strings is enabled). This fixes issue #35.
+        
+        - Fixed an issue where setting the ``filename`` attribute on a
+          file-based template would not automatically cause an invalidation.
+        
+        - Exceptions raised by Chameleon can now be copied via
+          ``copy.copy``. This fixes issue #36.
+          [leorochael]
+        
+        - If copying the exception fails in the exception handler, simply
+          re-raise the original exception and log a warning.
+        
+        2.2 (2011-07-28)
+        ----------------
+        
+        Features:
+        
+        - Added new expression type ``load:`` that allows loading a
+          template. Both relative and absolute paths are supported. If the
+          path given is relative, then it will be resolved with respect to the
+          directory of the template.
+        
+        - Added support for dynamic evaluation of expressions.
+        
+          Note that this is to support legacy applications. It is not
+          currently wired into the provided template classes.
+        
+        - Template classes now have a ``builtins`` attribute which may be used
+          to define built-in variables always available in the template
+          variable scope.
+        
+        Incompatibilities:
+        
+        - The file-based template class no longer accepts a parameter
+          ``loader``. This parameter would be used to load a template from a
+          relative path, using a ``find(filename)`` method. This was however,
+          undocumented, and probably not very useful since we have the
+          ``TemplateLoader`` mechanism already.
+        
+        - The compiled template module now contains an ``initialize`` function
+          which takes values that map to the template builtins. The return
+          value of this function is a dictionary that contains the render
+          functions.
+        
+        Bugfixes:
+        
+        - The file-based template class no longer verifies the existance of a
+          template file (using ``os.lstat``). This now happens implicitly if
+          eager parsing is enabled, or otherwise when first needed (e.g. at
+          render time).
+        
+          This is classified as a bug fix because the previous behavior was
+          probably not what you'd expect, especially if an application
+          initializes a lot of templates without needing to render them
+          immediately.
+        
+        2.1.1 (2011-07-28)
+        ------------------
+        
+        Features:
+        
+        - Improved exception display. The expression string is now shown in
+          the context of the original source (if available) with a marker
+          string indicating the location of the expression in the template
+          source.
+        
+        Bugfixes:
+        
+        - The ``structure`` insertion mode now correctly decodes entities for
+          any expression type (including ``string:``). This fixes issue #30.
+        
+        - Don't show internal variables in the exception formatter variable
+          listing.
+        
+        2.1 (2011-07-25)
+        ----------------
+        
+        Features:
+        
+        - Expression interpolation (using the ``${...}`` operator and
+          previously also ``$identifier``) now requires braces everywhere
+          except inside the ``string:`` expression type.
+        
+          This change is motivated by a number of legacy templates in which
+          the interpolation format without braces ``$identifier`` appears as
+          text.
+        
+        2.0.2 (2011-07-25)
+        ------------------
+        
+        Bugfixes:
+        
+        - Don't use dynamic variable scope for lambda-scoped variables (#27).
+        
+        - Avoid duplication of exception class and message in traceback.
+        
+        - Fixed issue where a ``metal:fill-slot`` would be ignored if a macro
+          was set to be used on the same element (#16).
+        
+        2.0.1 (2011-07-23)
+        ------------------
+        
+        Bugfixes:
+        
+        - Fixed issue where global variable definition from macro slots would
+          fail (they would instead be local). This also affects error
+          reporting from inside slots because this would be recorded
+          internally as a global.
+        
+        - Fixed issue with template cache digest (used for filenames); modules
+          are now invalidated whenever any changes are made to the
+          distribution set available (packages on ``sys.path``).
+        
+        - Fixed exception handler to better let exceptions propagate through
+          the renderer.
+        
+        - The disk-based module compiler now mangles template source filenames
+          such that the output Python module is valid and at root level (dots
+          and hyphens are replaced by an underscore). This fixes issue #17.
+        
+        - Fixed translations (i18n) on Python 2.5.
+        
+        2.0 (2011-07-14)
+        ----------------
+        
+        - Point release.
+        
+        2.0-rc14 (2011-07-13)
+        ---------------------
+        
+        Bugfixes:
+        
+        - The tab character (``\t``) is now parsed correctly when used inside
+          tags.
+        
+        Features:
+        
+        - The ``RepeatDict`` class now works as a proxy behind a seperate
+          dictionary instance.
+        
+        - Added template constructor option ``keep_body`` which is a flag
+          (also available as a class attribute) that controls whether to save
+          the template body input in the ``body`` attribute.
+        
+          This is disabled by default, unless debug-mode is enabled.
+        
+        - The page template loader class now accepts an optional ``formats``
+          argument which can be used to select an alternative template class.
+        
+        2.0-rc13 (2011-07-07)
+        ---------------------
+        
+        Bugfixes:
+        
+        - The backslash character (followed by optional whitespace and a line
+          break) was not correctly interpreted as a continuation for Python
+          expressions.
+        
+        Features:
+        
+        - The Python expression implementation is now more flexible for
+          external subclassing via a new ``parse`` method.
+        
+        2.0-rc12 (2011-07-04)
+        ---------------------
+        
+        Bugfixes:
+        
+        - Initial keyword arguments passed to a template now no longer "leak"
+          into the template variable space after a macro call.
+        
+        - An unexpected end tag is now an unrecoverable error.
+        
+        Features:
+        
+        - Improve exception output.
+        
+        2.0-rc11 (2011-05-26)
+        ---------------------
+        
+        Bugfixes:
+        
+        - Fixed issue where variable names that begin with an underscore were
+          seemingly allowed, but their use resulted in a compiler error.
+        
+        Features:
+        
+        - Template variable names are now allowed to be prefixed with a single
+          underscore, but not two or more (reserved for internal use).
+        
+          Examples of valid names::
+        
+            item
+            ITEM
+            _item
+            camelCase
+            underscore_delimited
+            help
+        
+        - Added support for Genshi's comment "drop" syntax::
+        
+            <!--! This comment will be dropped -->
+        
+          Note the additional exclamation (!) character.
+        
+          This fixes addresses issue #10.
+        
+        2.0-rc10 (2011-05-24)
+        ---------------------
+        
+        Bugfixes:
+        
+        - The ``tal:attributes`` statement now correctly operates
+          case-insensitive. The attribute name given in the statement will
+          replace an existing attribute with the same name, without respect to
+          case.
+        
+        Features:
+        
+        - Added ``meta:interpolation`` statement to control expression
+          interpolation setting.
+        
+          Strings that disable the setting: ``"off"`` and ``"false"``.
+          Strings that enable the setting: ``"on"`` and ``"true"``.
+        
+        - Expression interpolation now works inside XML comments.
+        
+        2.0-rc9 (2011-05-05)
+        --------------------
+        
+        Features:
+        
+        - Better debugging support for string decode and conversion. If a
+          naive join fails, each element in the output will now be attempted
+          coerced to unicode to try and trigger the failure near to the bad
+          string.
+        
+        2.0-rc8 (2011-04-11)
+        --------------------
+        
+        Bugfixes:
+        
+        - If a macro defines two slots with the same name, a caller will now
+          fill both with a single usage.
+        
+        - If a valid of ``None`` is provided as the translation function
+          argument, we now fall back to the class default.
+        
+        2.0-rc7 (2011-03-29)
+        --------------------
+        
+        Bugfixes:
+        
+        - Fixed issue with Python 2.5 compatibility AST. This affected at
+          least PyPy 1.4.
+        
+        Features:
+        
+        - The ``auto_reload`` setting now defaults to the class value; the
+          base template class gives a default value of
+          ``chameleon.config.AUTO_RELOAD``. This change allows a subclass to
+          provide a custom default value (such as an application-specific
+          debug mode setting).
+        
+        
+        2.0-rc6 (2011-03-19)
+        --------------------
+        
+        Features:
+        
+        - Added support for ``target_language`` keyword argument to render
+          method. If provided, the argument will be curried onto the
+          translation function.
+        
+        Bugfixes:
+        
+        - The HTML entities 'lt', 'gt' and 'quot' appearing inside content
+          subtition expressions are now translated into their native character
+          values. This fixes an issue where you could not dynamically create
+          elements using the ``structure`` (which is possible in ZPT). The
+          need to create such structure stems from the lack of an expression
+          interpolation operator in ZPT.
+        
+        - Fixed duplicate file pointer issue with test suite (affected Windows
+          platforms only). This fixes issue #9.
+          [oliora]
+        
+        - Use already open file using ``os.fdopen`` when trying to write out
+          the module source. This fixes LP #731803.
+        
+        
+        2.0-rc5 (2011-03-07)
+        --------------------
+        
+        Bugfixes:
+        
+        - Fixed a number of issues concerning the escaping of attribute
+          values:
+        
+          1) Static attribute values are now included as they appear in the
+             source.
+        
+             This means that invalid attribute values such as ``"true &&
+             false"`` are now left alone. It's not the job of the template
+             engine to correct such markup, at least not in the default mode
+             of operation.
+        
+          2) The string expression compiler no longer unescapes
+             values. Instead, this is left to each expression
+             compiler. Currently only the Python expression compiler unescapes
+             its input.
+        
+          3) The dynamic escape code sequence now correctly only replaces
+             ampersands that are part of an HTML escape format.
+        
+        Imports:
+        
+        - The page template classes and the loader class can now be imported
+          directly from the ``chameleon`` module.
+        
+        Features:
+        
+        - If a custom template loader is not provided, relative paths are now
+          resolved using ``os.abspath`` (i.e. to the current working
+          directory).
+        
+        - Absolute paths are normalized using ``os.path.normpath`` and
+          ``os.path.expanduser``. This ensures that all paths are kept in
+          their "canonical" form.
+        
+        
+        2.0-rc4 (2011-03-03)
+        --------------------
+        
+        Bugfixes:
+        
+        - Fixed an issue where the output of an end-to-end string expression
+          would raise an exception if the expression evaluated to ``None`` (it
+          should simply output nothing).
+        
+        - The ``convert`` function (which is configurable on the template
+          class level) now defaults to the ``translate`` function (at
+          run-time).
+        
+          This fixes an issue where message objects were not translated (and
+          thus converted to a string) using the a provided ``translate``
+          function.
+        
+        - Fixed string interpolation issue where an expression immediately
+          succeeded by a right curly bracket would not parse.
+        
+          This fixes issue #5.
+        
+        - Fixed error where ``tal:condition`` would be evaluated after
+          ``tal:repeat``.
+        
+        Features:
+        
+        - Python expression is now a TALES expression. That means that the
+          pipe operator can be used to chain two or more expressions in a
+          try-except sequence.
+        
+          This behavior was ported from the 1.x series. Note that while it's
+          still possible to use the pipe character ("|") in an expression, it
+          must now be escaped.
+        
+        - The template cache can now be shared by multiple processes.
+        
+        
+        2.0-rc3 (2011-03-02)
+        --------------------
+        
+        Bugfixes:
+        
+        - Fixed ``atexit`` handler.
+        
+          This fixes issue #3.
+        
+        - If a cache directory is specified, it will now be used even when not
+          in debug mode.
+        
+        - Allow "comment" attribute in the TAL namespace.
+        
+          This fixes an issue in the sense that the reference engine allows
+          any attribute within the TAL namespace. However, only "comment" is
+          in common use.
+        
+        - The template constructor now accepts a flag ``debug`` which puts the
+          template *instance* into debug-mode regardless of the global
+          setting.
+        
+          This fixes issue #1.
+        
+        Features:
+        
+        - Added exception handler for exceptions raised while evaluating an
+          expression.
+        
+          This handler raises (or attempts to) a new exception of the type
+          ``RenderError``, with an additional base class of the original
+          exception class. The string value of the exception is a formatted
+          error message which includes the expression that caused the
+          exception.
+        
+          If we are unable to create the exception class, the original
+          exception is re-raised.
+        
+        2.0-rc2 (2011-02-28)
+        --------------------
+        
+        - Fixed upload issue.
+        
+        2.0-rc1 (2011-02-28)
+        --------------------
+        
+        - Initial public release. See documentation for what's new in this
+          series.
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.1
+Classifier: Programming Language :: Python :: 3.2
diff --git a/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/SOURCES.txt b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/SOURCES.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/SOURCES.txt
@@ -0,0 +1,380 @@
+.gitignore
+CHANGES.rst
+COPYRIGHT.txt
+LICENSE.txt
+Makefile
+README.rst
+distribute_setup.py
+setup.cfg
+setup.py
+tox.ini
+benchmarks/bm_chameleon.py
+benchmarks/bm_mako.py
+benchmarks/util.py
+docs/conf.py
+docs/configuration.rst
+docs/index.rst
+docs/integration.rst
+docs/library.rst
+docs/reference.rst
+src/Chameleon.egg-info/PKG-INFO
+src/Chameleon.egg-info/SOURCES.txt
+src/Chameleon.egg-info/dependency_links.txt
+src/Chameleon.egg-info/not-zip-safe
+src/Chameleon.egg-info/top_level.txt
+src/chameleon/__init__.py
+src/chameleon/ast24.py
+src/chameleon/astutil.py
+src/chameleon/benchmark.py
+src/chameleon/codegen.py
+src/chameleon/compiler.py
+src/chameleon/config.py
+src/chameleon/exc.py
+src/chameleon/i18n.py
+src/chameleon/interfaces.py
+src/chameleon/loader.py
+src/chameleon/metal.py
+src/chameleon/namespaces.py
+src/chameleon/nodes.py
+src/chameleon/parser.py
+src/chameleon/program.py
+src/chameleon/py25.py
+src/chameleon/py26.py
+src/chameleon/tal.py
+src/chameleon/tales.py
+src/chameleon/template.py
+src/chameleon/tokenize.py
+src/chameleon/utils.py
+src/chameleon/tests/__init__.py
+src/chameleon/tests/test_doctests.py
+src/chameleon/tests/test_loader.py
+src/chameleon/tests/test_parser.py
+src/chameleon/tests/test_sniffing.py
+src/chameleon/tests/test_templates.py
+src/chameleon/tests/test_tokenizer.py
+src/chameleon/tests/inputs/001-interpolation.txt
+src/chameleon/tests/inputs/001-variable-scope.html
+src/chameleon/tests/inputs/001-variable-scope.pt
+src/chameleon/tests/inputs/001.xml
+src/chameleon/tests/inputs/002-repeat-scope.pt
+src/chameleon/tests/inputs/002.xml
+src/chameleon/tests/inputs/003-content.pt
+src/chameleon/tests/inputs/003.xml
+src/chameleon/tests/inputs/004-attributes.pt
+src/chameleon/tests/inputs/004.xml
+src/chameleon/tests/inputs/005-default.pt
+src/chameleon/tests/inputs/005.xml
+src/chameleon/tests/inputs/006-attribute-interpolation.pt
+src/chameleon/tests/inputs/006.xml
+src/chameleon/tests/inputs/007-content-interpolation.pt
+src/chameleon/tests/inputs/007.xml
+src/chameleon/tests/inputs/008-builtins.pt
+src/chameleon/tests/inputs/008.xml
+src/chameleon/tests/inputs/009-literals.pt
+src/chameleon/tests/inputs/009.xml
+src/chameleon/tests/inputs/010-structure.pt
+src/chameleon/tests/inputs/010.xml
+src/chameleon/tests/inputs/011-messages.pt
+src/chameleon/tests/inputs/011.xml
+src/chameleon/tests/inputs/012-translation.pt
+src/chameleon/tests/inputs/012.xml
+src/chameleon/tests/inputs/013-repeat-nested.pt
+src/chameleon/tests/inputs/013.xml
+src/chameleon/tests/inputs/014-repeat-nested-similar.pt
+src/chameleon/tests/inputs/014.xml
+src/chameleon/tests/inputs/015-translation-nested.pt
+src/chameleon/tests/inputs/015.xml
+src/chameleon/tests/inputs/016-explicit-translation.pt
+src/chameleon/tests/inputs/016.xml
+src/chameleon/tests/inputs/017-omit-tag.pt
+src/chameleon/tests/inputs/017.xml
+src/chameleon/tests/inputs/018-translation-nested-dynamic.pt
+src/chameleon/tests/inputs/018.xml
+src/chameleon/tests/inputs/019-replace.pt
+src/chameleon/tests/inputs/019.xml
+src/chameleon/tests/inputs/020-on-error.pt
+src/chameleon/tests/inputs/020.xml
+src/chameleon/tests/inputs/021-translation-domain.pt
+src/chameleon/tests/inputs/021.xml
+src/chameleon/tests/inputs/022-switch.pt
+src/chameleon/tests/inputs/022.xml
+src/chameleon/tests/inputs/023-condition.pt
+src/chameleon/tests/inputs/023.xml
+src/chameleon/tests/inputs/024-namespace-elements.pt
+src/chameleon/tests/inputs/024.xml
+src/chameleon/tests/inputs/025-repeat-whitespace.pt
+src/chameleon/tests/inputs/025.xml
+src/chameleon/tests/inputs/026-repeat-variable.pt
+src/chameleon/tests/inputs/026.xml
+src/chameleon/tests/inputs/027-attribute-replacement.pt
+src/chameleon/tests/inputs/027.xml
+src/chameleon/tests/inputs/028-attribute-toggle.pt
+src/chameleon/tests/inputs/028.xml
+src/chameleon/tests/inputs/029-attribute-ordering.pt
+src/chameleon/tests/inputs/029.xml
+src/chameleon/tests/inputs/030-repeat-tuples.pt
+src/chameleon/tests/inputs/030.xml
+src/chameleon/tests/inputs/031-namespace-with-tal.pt
+src/chameleon/tests/inputs/031.xml
+src/chameleon/tests/inputs/032-master-template.pt
+src/chameleon/tests/inputs/032.xml
+src/chameleon/tests/inputs/033-use-macro-trivial.pt
+src/chameleon/tests/inputs/033.xml
+src/chameleon/tests/inputs/034-use-template-as-macro.pt
+src/chameleon/tests/inputs/034.xml
+src/chameleon/tests/inputs/035-use-macro-with-fill-slot.pt
+src/chameleon/tests/inputs/035.xml
+src/chameleon/tests/inputs/036-use-macro-inherits-dynamic-scope.pt
+src/chameleon/tests/inputs/036.xml
+src/chameleon/tests/inputs/037-use-macro-local-variable-scope.pt
+src/chameleon/tests/inputs/037.xml
+src/chameleon/tests/inputs/038-use-macro-globals.pt
+src/chameleon/tests/inputs/038.xml
+src/chameleon/tests/inputs/039-globals.pt
+src/chameleon/tests/inputs/039.xml
+src/chameleon/tests/inputs/040-macro-using-template-symbol.pt
+src/chameleon/tests/inputs/040.xml
+src/chameleon/tests/inputs/041-translate-nested-names.pt
+src/chameleon/tests/inputs/041.xml
+src/chameleon/tests/inputs/042-use-macro-fill-footer.pt
+src/chameleon/tests/inputs/042.xml
+src/chameleon/tests/inputs/043-macro-nested-dynamic-vars.pt
+src/chameleon/tests/inputs/043.xml
+src/chameleon/tests/inputs/044-tuple-define.pt
+src/chameleon/tests/inputs/044.xml
+src/chameleon/tests/inputs/045-namespaces.pt
+src/chameleon/tests/inputs/045.xml
+src/chameleon/tests/inputs/046-extend-macro.pt
+src/chameleon/tests/inputs/046.xml
+src/chameleon/tests/inputs/047-use-extended-macro.pt
+src/chameleon/tests/inputs/047.xml
+src/chameleon/tests/inputs/048-use-extended-macro-fill-original.pt
+src/chameleon/tests/inputs/048.xml
+src/chameleon/tests/inputs/049-entities-in-attributes.pt
+src/chameleon/tests/inputs/049.xml
+src/chameleon/tests/inputs/050-define-macro-and-use-not-extend.pt
+src/chameleon/tests/inputs/050.xml
+src/chameleon/tests/inputs/051-use-non-extended-macro.pt
+src/chameleon/tests/inputs/051.xml
+src/chameleon/tests/inputs/052-i18n-domain-inside-filled-slot.pt
+src/chameleon/tests/inputs/052.xml
+src/chameleon/tests/inputs/053-special-characters-in-attributes.pt
+src/chameleon/tests/inputs/053.xml
+src/chameleon/tests/inputs/054-import-expression.pt
+src/chameleon/tests/inputs/054.xml
+src/chameleon/tests/inputs/055-attribute-fallback-to-dict-lookup.pt
+src/chameleon/tests/inputs/055.xml
+src/chameleon/tests/inputs/056-comment-attribute.pt
+src/chameleon/tests/inputs/056.xml
+src/chameleon/tests/inputs/057-order.pt
+src/chameleon/tests/inputs/057.xml
+src/chameleon/tests/inputs/058-script.pt
+src/chameleon/tests/inputs/058.xml
+src/chameleon/tests/inputs/059-embedded-javascript.pt
+src/chameleon/tests/inputs/059.xml
+src/chameleon/tests/inputs/060-macro-with-multiple-same-slots.pt
+src/chameleon/tests/inputs/060.xml
+src/chameleon/tests/inputs/061-fill-one-slot-but-two-defined.pt
+src/chameleon/tests/inputs/061.xml
+src/chameleon/tests/inputs/062-comments-and-expressions.pt
+src/chameleon/tests/inputs/062.xml
+src/chameleon/tests/inputs/063-continuation.pt
+src/chameleon/tests/inputs/063.xml
+src/chameleon/tests/inputs/064-tags-and-special-characters.pt
+src/chameleon/tests/inputs/064.xml
+src/chameleon/tests/inputs/065-use-macro-in-fill.pt
+src/chameleon/tests/inputs/065.xml
+src/chameleon/tests/inputs/066-load-expression.pt
+src/chameleon/tests/inputs/066.xml
+src/chameleon/tests/inputs/067-attribute-decode.pt
+src/chameleon/tests/inputs/067.xml
+src/chameleon/tests/inputs/068-less-than-greater-than-in-attributes.pt
+src/chameleon/tests/inputs/068.xml
+src/chameleon/tests/inputs/069-translation-domain-and-macro.pt
+src/chameleon/tests/inputs/069.xml
+src/chameleon/tests/inputs/070-translation-domain-and-use-macro.pt
+src/chameleon/tests/inputs/070.xml
+src/chameleon/tests/inputs/071-html-attribute-defaults.pt
+src/chameleon/tests/inputs/071.xml
+src/chameleon/tests/inputs/072-repeat-interpolation.pt
+src/chameleon/tests/inputs/072.xml
+src/chameleon/tests/inputs/073-utf8-encoded.pt
+src/chameleon/tests/inputs/073.xml
+src/chameleon/tests/inputs/074-encoded-template.pt
+src/chameleon/tests/inputs/074.xml
+src/chameleon/tests/inputs/075-nested-macros.pt
+src/chameleon/tests/inputs/075.xml
+src/chameleon/tests/inputs/076-nested-macro-override.pt
+src/chameleon/tests/inputs/076.xml
+src/chameleon/tests/inputs/077-i18n-attributes.pt
+src/chameleon/tests/inputs/077.xml
+src/chameleon/tests/inputs/078-tags-and-newlines.pt
+src/chameleon/tests/inputs/078.xml
+src/chameleon/tests/inputs/079-implicit-i18n.pt
+src/chameleon/tests/inputs/079.xml
+src/chameleon/tests/inputs/080-xmlns-namespace-on-tal.pt
+src/chameleon/tests/inputs/080.xml
+src/chameleon/tests/inputs/081-load-spec.pt
+src/chameleon/tests/inputs/081.xml
+src/chameleon/tests/inputs/082-load-spec-computed.pt
+src/chameleon/tests/inputs/082.xml
+src/chameleon/tests/inputs/083-template-dict-to-macro.pt
+src/chameleon/tests/inputs/083.xml
+src/chameleon/tests/inputs/084-interpolation-in-cdata.pt
+src/chameleon/tests/inputs/084.xml
+src/chameleon/tests/inputs/085-nested-translation.pt
+src/chameleon/tests/inputs/085.xml
+src/chameleon/tests/inputs/086-self-closing.pt
+src/chameleon/tests/inputs/086.xml
+src/chameleon/tests/inputs/087-code-blocks.pt
+src/chameleon/tests/inputs/087.xml
+src/chameleon/tests/inputs/088-python-newlines.pt
+src/chameleon/tests/inputs/088.xml
+src/chameleon/tests/inputs/089.xml
+src/chameleon/tests/inputs/090.xml
+src/chameleon/tests/inputs/091.xml
+src/chameleon/tests/inputs/092.xml
+src/chameleon/tests/inputs/093.xml
+src/chameleon/tests/inputs/094.xml
+src/chameleon/tests/inputs/095.xml
+src/chameleon/tests/inputs/096.xml
+src/chameleon/tests/inputs/097.xml
+src/chameleon/tests/inputs/098.xml
+src/chameleon/tests/inputs/099.xml
+src/chameleon/tests/inputs/100.xml
+src/chameleon/tests/inputs/101-unclosed-tags.html
+src/chameleon/tests/inputs/101.xml
+src/chameleon/tests/inputs/102-unquoted-attributes.html
+src/chameleon/tests/inputs/102.xml
+src/chameleon/tests/inputs/103-simple-attribute.html
+src/chameleon/tests/inputs/103.xml
+src/chameleon/tests/inputs/104.xml
+src/chameleon/tests/inputs/105.xml
+src/chameleon/tests/inputs/106.xml
+src/chameleon/tests/inputs/107.xml
+src/chameleon/tests/inputs/108.xml
+src/chameleon/tests/inputs/109.xml
+src/chameleon/tests/inputs/110.xml
+src/chameleon/tests/inputs/111.xml
+src/chameleon/tests/inputs/112.xml
+src/chameleon/tests/inputs/113.xml
+src/chameleon/tests/inputs/114.xml
+src/chameleon/tests/inputs/115.xml
+src/chameleon/tests/inputs/116.xml
+src/chameleon/tests/inputs/117.xml
+src/chameleon/tests/inputs/118.xml
+src/chameleon/tests/inputs/119.xml
+src/chameleon/tests/inputs/greeting.pt
+src/chameleon/tests/inputs/hello_world.pt
+src/chameleon/tests/inputs/hello_world.txt
+src/chameleon/tests/outputs/001.html
+src/chameleon/tests/outputs/001.pt
+src/chameleon/tests/outputs/001.txt
+src/chameleon/tests/outputs/002.pt
+src/chameleon/tests/outputs/003.pt
+src/chameleon/tests/outputs/004.pt
+src/chameleon/tests/outputs/005.pt
+src/chameleon/tests/outputs/006.pt
+src/chameleon/tests/outputs/007.pt
+src/chameleon/tests/outputs/008.pt
+src/chameleon/tests/outputs/009.pt
+src/chameleon/tests/outputs/010.pt
+src/chameleon/tests/outputs/011-en.pt
+src/chameleon/tests/outputs/011.pt
+src/chameleon/tests/outputs/012-en.pt
+src/chameleon/tests/outputs/012.pt
+src/chameleon/tests/outputs/013.pt
+src/chameleon/tests/outputs/014.pt
+src/chameleon/tests/outputs/015-en.pt
+src/chameleon/tests/outputs/015.pt
+src/chameleon/tests/outputs/016-en.pt
+src/chameleon/tests/outputs/016.pt
+src/chameleon/tests/outputs/017.pt
+src/chameleon/tests/outputs/018-en.pt
+src/chameleon/tests/outputs/018.pt
+src/chameleon/tests/outputs/019.pt
+src/chameleon/tests/outputs/020.pt
+src/chameleon/tests/outputs/021-en.pt
+src/chameleon/tests/outputs/021.pt
+src/chameleon/tests/outputs/022.pt
+src/chameleon/tests/outputs/023.pt
+src/chameleon/tests/outputs/024.pt
+src/chameleon/tests/outputs/025.pt
+src/chameleon/tests/outputs/026.pt
+src/chameleon/tests/outputs/027.pt
+src/chameleon/tests/outputs/028.pt
+src/chameleon/tests/outputs/029.pt
+src/chameleon/tests/outputs/030.pt
+src/chameleon/tests/outputs/031.pt
+src/chameleon/tests/outputs/032.pt
+src/chameleon/tests/outputs/033.pt
+src/chameleon/tests/outputs/034.pt
+src/chameleon/tests/outputs/035.pt
+src/chameleon/tests/outputs/036.pt
+src/chameleon/tests/outputs/037.pt
+src/chameleon/tests/outputs/038.pt
+src/chameleon/tests/outputs/039.pt
+src/chameleon/tests/outputs/040.pt
+src/chameleon/tests/outputs/041.pt
+src/chameleon/tests/outputs/042.pt
+src/chameleon/tests/outputs/043.pt
+src/chameleon/tests/outputs/044.pt
+src/chameleon/tests/outputs/045.pt
+src/chameleon/tests/outputs/046.pt
+src/chameleon/tests/outputs/047.pt
+src/chameleon/tests/outputs/048.pt
+src/chameleon/tests/outputs/049.pt
+src/chameleon/tests/outputs/050.pt
+src/chameleon/tests/outputs/051.pt
+src/chameleon/tests/outputs/052.pt
+src/chameleon/tests/outputs/053.pt
+src/chameleon/tests/outputs/054.pt
+src/chameleon/tests/outputs/055.pt
+src/chameleon/tests/outputs/056.pt
+src/chameleon/tests/outputs/057.pt
+src/chameleon/tests/outputs/058.pt
+src/chameleon/tests/outputs/059.pt
+src/chameleon/tests/outputs/060.pt
+src/chameleon/tests/outputs/061.pt
+src/chameleon/tests/outputs/062.pt
+src/chameleon/tests/outputs/063.pt
+src/chameleon/tests/outputs/064.pt
+src/chameleon/tests/outputs/065.pt
+src/chameleon/tests/outputs/066.pt
+src/chameleon/tests/outputs/067.pt
+src/chameleon/tests/outputs/068.pt
+src/chameleon/tests/outputs/069-en.pt
+src/chameleon/tests/outputs/069.pt
+src/chameleon/tests/outputs/070-en.pt
+src/chameleon/tests/outputs/070.pt
+src/chameleon/tests/outputs/071.pt
+src/chameleon/tests/outputs/072.pt
+src/chameleon/tests/outputs/073.pt
+src/chameleon/tests/outputs/074.pt
+src/chameleon/tests/outputs/075.pt
+src/chameleon/tests/outputs/076.pt
+src/chameleon/tests/outputs/077-en.pt
+src/chameleon/tests/outputs/077.pt
+src/chameleon/tests/outputs/078.pt
+src/chameleon/tests/outputs/079-en.pt
+src/chameleon/tests/outputs/079.pt
+src/chameleon/tests/outputs/080.pt
+src/chameleon/tests/outputs/081.pt
+src/chameleon/tests/outputs/082.pt
+src/chameleon/tests/outputs/083.pt
+src/chameleon/tests/outputs/084.pt
+src/chameleon/tests/outputs/085-en.pt
+src/chameleon/tests/outputs/085.pt
+src/chameleon/tests/outputs/086.pt
+src/chameleon/tests/outputs/087.pt
+src/chameleon/tests/outputs/088.pt
+src/chameleon/tests/outputs/101.html
+src/chameleon/tests/outputs/102.html
+src/chameleon/tests/outputs/103.html
+src/chameleon/tests/outputs/greeting.pt
+src/chameleon/tests/outputs/hello_world.pt
+src/chameleon/tests/outputs/hello_world.txt
+src/chameleon/zpt/__init__.py
+src/chameleon/zpt/loader.py
+src/chameleon/zpt/program.py
+src/chameleon/zpt/template.py
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/dependency_links.txt b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/dependency_links.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/dependency_links.txt
@@ -0,0 +1,1 @@
+
diff --git a/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/not-zip-safe b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/not-zip-safe
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/not-zip-safe
@@ -0,0 +1,1 @@
+
diff --git a/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/top_level.txt b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/top_level.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/Chameleon.egg-info/top_level.txt
@@ -0,0 +1,1 @@
+chameleon
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/__init__.py b/lib3/Chameleon-2.9.2/src/chameleon/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/__init__.py
@@ -0,0 +1,5 @@
+from .zpt.template import PageTemplate
+from .zpt.template import PageTemplateFile
+from .zpt.template import PageTextTemplate
+from .zpt.template import PageTextTemplateFile
+from .zpt.loader import TemplateLoader as PageTemplateLoader
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/ast24.py b/lib3/Chameleon-2.9.2/src/chameleon/ast24.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/ast24.py
@@ -0,0 +1,135 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright 2008 by Armin Ronacher.
+# License: Python License.
+#
+
+import _ast
+
+from _ast import *
+
+
+def fix_missing_locations(node):
+    """
+    When you compile a node tree with compile(), the compiler expects lineno and
+    col_offset attributes for every node that supports them.  This is rather
+    tedious to fill in for generated nodes, so this helper adds these attributes
+    recursively where not already set, by setting them to the values of the
+    parent node.  It works recursively starting at *node*.
+    """
+    def _fix(node, lineno, col_offset):
+        if 'lineno' in node._attributes:
+            if not hasattr(node, 'lineno'):
+                node.lineno = lineno
+            else:
+                lineno = node.lineno
+        if 'col_offset' in node._attributes:
+            if not hasattr(node, 'col_offset'):
+                node.col_offset = col_offset
+            else:
+                col_offset = node.col_offset
+        for child in iter_child_nodes(node):
+            _fix(child, lineno, col_offset)
+    _fix(node, 1, 0)
+    return node
+
+
+def iter_child_nodes(node):
+    """
+    Yield all direct child nodes of *node*, that is, all fields that are nodes
+    and all items of fields that are lists of nodes.
+    """
+    for name, field in iter_fields(node):
+        if isinstance(field, (AST, _ast.AST)):
+            yield field
+        elif isinstance(field, list):
+            for item in field:
+                if isinstance(item, (AST, _ast.AST)):
+                    yield item
+
+
+def iter_fields(node):
+    """
+    Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields``
+    that is present on *node*.
+    """
+
+    for field in node._fields or ():
+        try:
+            yield field, getattr(node, field)
+        except AttributeError:
+            pass
+
+
+def walk(node):
+    """
+    Recursively yield all child nodes of *node*, in no specified order.  This is
+    useful if you only want to modify nodes in place and don't care about the
+    context.
+    """
+    from collections import deque
+    todo = deque([node])
+    while todo:
+        node = todo.popleft()
+        todo.extend(iter_child_nodes(node))
+        yield node
+
+
+class NodeVisitor(object):
+    """
+    A node visitor base class that walks the abstract syntax tree and calls a
+    visitor function for every node found.  This function may return a value
+    which is forwarded by the `visit` method.
+
+    This class is meant to be subclassed, with the subclass adding visitor
+    methods.
+
+    Per default the visitor functions for the nodes are ``'visit_'`` +
+    class name of the node.  So a `TryFinally` node visit function would
+    be `visit_TryFinally`.  This behavior can be changed by overriding
+    the `visit` method.  If no visitor function exists for a node
+    (return value `None`) the `generic_visit` visitor is used instead.
+
+    Don't use the `NodeVisitor` if you want to apply changes to nodes during
+    traversing.  For this a special visitor exists (`NodeTransformer`) that
+    allows modifications.
+    """
+
+    def visit(self, node):
+        """Visit a node."""
+        method = 'visit_' + node.__class__.__name__
+        visitor = getattr(self, method, self.generic_visit)
+        return visitor(node)
+
+    def generic_visit(self, node):
+        """Called if no explicit visitor function exists for a node."""
+        for field, value in iter_fields(node):
+            if isinstance(value, list):
+                for item in value:
+                    if isinstance(item, (AST, _ast.AST)):
+                        self.visit(item)
+            elif isinstance(value, (AST, _ast.AST)):
+                self.visit(value)
+
+
+class AST(object):
+    _fields = ()
+    _attributes = 'lineno', 'col_offset'
+
+    def __init__(self, *args, **kwargs):
+        self.__dict__.update(kwargs)
+        self._fields = self._fields or ()
+        for name, value in zip(self._fields, args):
+            setattr(self, name, value)
+
+
+for name, cls in _ast.__dict__.items():
+    if isinstance(cls, type) and issubclass(cls, _ast.AST):
+        try:
+            cls.__bases__ = (AST, ) + cls.__bases__
+        except TypeError:
+            pass
+
+
+class ExceptHandler(AST):
+    _fields = "type", "name", "body"
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/astutil.py b/lib3/Chameleon-2.9.2/src/chameleon/astutil.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/astutil.py
@@ -0,0 +1,926 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008-2009 Edgewall Software
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://genshi.edgewall.org/wiki/License.
+#
+# This software consists of voluntary contributions made by many
+# individuals. For the exact contribution history, see the revision
+# history and logs, available at http://genshi.edgewall.org/log/.
+
+"""Support classes for generating code from abstract syntax trees."""
+
+try:
+    import ast
+except ImportError:
+    from chameleon import ast24 as ast
+
+import sys
+import logging
+import weakref
+
+node_annotations = weakref.WeakKeyDictionary()
+
+try:
+    node_annotations[ast.Name()] = None
+except TypeError:
+    logging.debug(
+        "Unable to create weak references to AST nodes. " \
+        "A lock will be used around compilation loop."
+        )
+
+    node_annotations = {}
+
+__docformat__ = 'restructuredtext en'
+
+
+def annotated(value):
+    node = load("annotation")
+    node_annotations[node] = value
+    return node
+
+
+def parse(source, mode='eval'):
+    return compile(source, '', mode, ast.PyCF_ONLY_AST)
+
+
+def load(name):
+    return ast.Name(id=name, ctx=ast.Load())
+
+
+def store(name):
+    return ast.Name(id=name, ctx=ast.Store())
+
+
+def param(name):
+    return ast.Name(id=name, ctx=ast.Param())
+
+
+def delete(name):
+    return ast.Name(id=name, ctx=ast.Del())
+
+
+def subscript(name, value, ctx):
+    return ast.Subscript(
+        value=value,
+        slice=ast.Index(value=ast.Str(s=name)),
+        ctx=ctx,
+        )
+
+
+def walk_names(target, mode):
+    for node in ast.walk(target):
+        if isinstance(node, ast.Name) and \
+               isinstance(node.ctx, mode):
+            yield node.id
+
+
+def copy(source, target):
+    target.__class__ = source.__class__
+    target.__dict__ = source.__dict__
+
+
+def swap(root, replacement, name):
+    for node in ast.walk(root):
+        if (isinstance(node, ast.Name) and
+            isinstance(node.ctx, ast.Load) and
+            node.id == name):
+            assert hasattr(replacement, '_fields')
+            node_annotations.setdefault(node, replacement)
+
+
+def marker(name):
+    return ast.Str(s="__%s" % name)
+
+
+class Node(object):
+    """AST baseclass that gives us a convenient initialization
+    method. We explicitly declare and use the ``_fields`` attribute."""
+
+    _fields = ()
+
+    def __init__(self, *args, **kwargs):
+        assert isinstance(self._fields, tuple)
+        self.__dict__.update(kwargs)
+        for name, value in zip(self._fields, args):
+            setattr(self, name, value)
+
+    def __repr__(self):
+        """Poor man's single-line pretty printer."""
+
+        name = type(self).__name__
+        return '<%s%s at %x>' % (
+            name,
+            "".join(" %s=%r" % (name, getattr(self, name, "\"?\""))
+                        for name in self._fields),
+            id(self)
+            )
+
+
+class Builtin(Node):
+    """Represents a Python builtin.
+
+    Used when a builtin is used internally by the compiler, to avoid
+    clashing with a user assignment (e.g. ``help`` is a builtin, but
+    also commonly assigned in templates).
+    """
+
+    _fields = "id", "ctx"
+
+    ctx = ast.Load()
+
+
+class Symbol(Node):
+    """Represents an importable symbol."""
+
+    _fields = "value",
+
+
+class Static(Node):
+    """Represents a static value."""
+
+    _fields = "value", "name"
+
+    name = None
+
+
+class Comment(Node):
+    _fields = "text", "space", "stmt"
+
+    stmt = None
+    space = ""
+
+
+class ASTCodeGenerator(object):
+    """General purpose base class for AST transformations.
+
+    Every visitor method can be overridden to return an AST node that has been
+    altered or replaced in some way.
+    """
+
+    def __init__(self, tree):
+        self.lines_info = []
+        self.line_info = []
+        self.lines = []
+        self.line = ""
+        self.last = None
+        self.indent = 0
+        self.blame_stack = []
+        self.visit(tree)
+
+        if self.line.strip():
+            self._new_line()
+
+        self.line = None
+        self.line_info = None
+
+        # strip trivial lines
+        self.code = "\n".join(
+            line.strip() and line or ""
+            for line in self.lines
+            )
+
+    def _change_indent(self, delta):
+        self.indent += delta
+
+    def _new_line(self):
+        if self.line is not None:
+            self.lines.append(self.line)
+            self.lines_info.append(self.line_info)
+        self.line = ' ' * 4 * self.indent
+        if len(self.blame_stack) == 0:
+            self.line_info = []
+            self.last = None
+        else:
+            self.line_info = [(0, self.blame_stack[-1],)]
+            self.last = self.blame_stack[-1]
+
+    def _write(self, s):
+        if len(s) == 0:
+            return
+        if len(self.blame_stack) == 0:
+            if self.last is not None:
+                self.last = None
+                self.line_info.append((len(self.line), self.last))
+        else:
+            if self.last != self.blame_stack[-1]:
+                self.last = self.blame_stack[-1]
+                self.line_info.append((len(self.line), self.last))
+        self.line += s
+
+    def flush(self):
+        if self.line:
+            self._new_line()
+
+    def visit(self, node):
+        if node is None:
+            return None
+        if type(node) is tuple:
+            return tuple([self.visit(n) for n in node])
+        try:
+            self.blame_stack.append((node.lineno, node.col_offset,))
+            info = True
+        except AttributeError:
+            info = False
+        visitor = getattr(self, 'visit_%s' % node.__class__.__name__, None)
+        if visitor is None:
+            raise Exception('No handler for ``%s`` (%s).' % (
+                node.__class__.__name__, repr(node)))
+        ret = visitor(node)
+        if info:
+            self.blame_stack.pop()
+        return ret
+
+    def visit_Module(self, node):
+        for n in node.body:
+            self.visit(n)
+    visit_Interactive = visit_Module
+    visit_Suite = visit_Module
+
+    def visit_Expression(self, node):
+        return self.visit(node.body)
+
+    # arguments = (expr* args, identifier? vararg,
+    #              identifier? kwarg, expr* defaults)
+    def visit_arguments(self, node):
+        first = True
+        no_default_count = len(node.args) - len(node.defaults)
+        for i, arg in enumerate(node.args):
+            if not first:
+                self._write(', ')
+            else:
+                first = False
+            self.visit(arg)
+            if i >= no_default_count:
+                self._write('=')
+                self.visit(node.defaults[i - no_default_count])
+        if getattr(node, 'vararg', None):
+            if not first:
+                self._write(', ')
+            else:
+                first = False
+            self._write('*' + node.vararg)
+        if getattr(node, 'kwarg', None):
+            if not first:
+                self._write(', ')
+            else:
+                first = False
+            self._write('**' + node.kwarg)
+
+    def visit_arg(self, node):
+        self._write(node.arg)
+
+    # FunctionDef(identifier name, arguments args,
+    #                           stmt* body, expr* decorators)
+    def visit_FunctionDef(self, node):
+        self._new_line()
+        for decorator in getattr(node, 'decorator_list', ()):
+            self._new_line()
+            self._write('@')
+            self.visit(decorator)
+        self._new_line()
+        self._write('def ' + node.name + '(')
+        self.visit(node.args)
+        self._write('):')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+
+    # ClassDef(identifier name, expr* bases, stmt* body)
+    def visit_ClassDef(self, node):
+        self._new_line()
+        self._write('class ' + node.name)
+        if node.bases:
+            self._write('(')
+            self.visit(node.bases[0])
+            for base in node.bases[1:]:
+                self._write(', ')
+                self.visit(base)
+            self._write(')')
+        self._write(':')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+
+    # Return(expr? value)
+    def visit_Return(self, node):
+        self._new_line()
+        self._write('return')
+        if getattr(node, 'value', None):
+            self._write(' ')
+            self.visit(node.value)
+
+    # Delete(expr* targets)
+    def visit_Delete(self, node):
+        self._new_line()
+        self._write('del ')
+        self.visit(node.targets[0])
+        for target in node.targets[1:]:
+            self._write(', ')
+            self.visit(target)
+
+    # Assign(expr* targets, expr value)
+    def visit_Assign(self, node):
+        self._new_line()
+        for target in node.targets:
+            self.visit(target)
+            self._write(' = ')
+        self.visit(node.value)
+
+    # AugAssign(expr target, operator op, expr value)
+    def visit_AugAssign(self, node):
+        self._new_line()
+        self.visit(node.target)
+        self._write(' ' + self.binary_operators[node.op.__class__] + '= ')
+        self.visit(node.value)
+
+    # Print(expr? dest, expr* values, bool nl)
+    def visit_Print(self, node):
+        self._new_line()
+        self._write('print')
+        if getattr(node, 'dest', None):
+            self._write(' >> ')
+            self.visit(node.dest)
+            if getattr(node, 'values', None):
+                self._write(', ')
+        else:
+            self._write(' ')
+        if getattr(node, 'values', None):
+            self.visit(node.values[0])
+            for value in node.values[1:]:
+                self._write(', ')
+                self.visit(value)
+        if not node.nl:
+            self._write(',')
+
+    # For(expr target, expr iter, stmt* body, stmt* orelse)
+    def visit_For(self, node):
+        self._new_line()
+        self._write('for ')
+        self.visit(node.target)
+        self._write(' in ')
+        self.visit(node.iter)
+        self._write(':')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+        if getattr(node, 'orelse', None):
+            self._new_line()
+            self._write('else:')
+            self._change_indent(1)
+            for statement in node.orelse:
+                self.visit(statement)
+            self._change_indent(-1)
+
+    # While(expr test, stmt* body, stmt* orelse)
+    def visit_While(self, node):
+        self._new_line()
+        self._write('while ')
+        self.visit(node.test)
+        self._write(':')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+        if getattr(node, 'orelse', None):
+            self._new_line()
+            self._write('else:')
+            self._change_indent(1)
+            for statement in node.orelse:
+                self.visit(statement)
+            self._change_indent(-1)
+
+    # If(expr test, stmt* body, stmt* orelse)
+    def visit_If(self, node):
+        self._new_line()
+        self._write('if ')
+        self.visit(node.test)
+        self._write(':')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+        if getattr(node, 'orelse', None):
+            self._new_line()
+            self._write('else:')
+            self._change_indent(1)
+            for statement in node.orelse:
+                self.visit(statement)
+            self._change_indent(-1)
+
+    # With(expr context_expr, expr? optional_vars, stmt* body)
+    def visit_With(self, node):
+        self._new_line()
+        self._write('with ')
+        self.visit(node.context_expr)
+        if getattr(node, 'optional_vars', None):
+            self._write(' as ')
+            self.visit(node.optional_vars)
+        self._write(':')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+
+    # Raise(expr? type, expr? inst, expr? tback)
+    def visit_Raise(self, node):
+        self._new_line()
+        self._write('raise')
+        if not getattr(node, "type", None):
+            exc = getattr(node, "exc", None)
+            if exc is None:
+                return
+            self._write(' ')
+            return self.visit(exc)
+        self._write(' ')
+        self.visit(node.type)
+        if not node.inst:
+            return
+        self._write(', ')
+        self.visit(node.inst)
+        if not node.tback:
+            return
+        self._write(', ')
+        self.visit(node.tback)
+
+    # Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
+    def visit_Try(self, node):
+        self._new_line()
+        self._write('try:')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+        if getattr(node, 'handlers', None):
+            for handler in node.handlers:
+                self.visit(handler)
+        self._new_line()
+
+        if getattr(node, 'orelse', None):
+            self._write('else:')
+            self._change_indent(1)
+            for statement in node.orelse:
+                self.visit(statement)
+            self._change_indent(-1)
+
+        if getattr(node, 'finalbody', None):
+            self._new_line()
+            self._write('finally:')
+            self._change_indent(1)
+            for statement in node.finalbody:
+                self.visit(statement)
+            self._change_indent(-1)
+
+    # TryExcept(stmt* body, excepthandler* handlers, stmt* orelse)
+    def visit_TryExcept(self, node):
+        self._new_line()
+        self._write('try:')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+        if getattr(node, 'handlers', None):
+            for handler in node.handlers:
+                self.visit(handler)
+        self._new_line()
+        if getattr(node, 'orelse', None):
+            self._write('else:')
+            self._change_indent(1)
+            for statement in node.orelse:
+                self.visit(statement)
+            self._change_indent(-1)
+
+    # excepthandler = (expr? type, expr? name, stmt* body)
+    def visit_ExceptHandler(self, node):
+        self._new_line()
+        self._write('except')
+        if getattr(node, 'type', None):
+            self._write(' ')
+            self.visit(node.type)
+        if getattr(node, 'name', None):
+            if sys.version_info[0] == 2:
+                assert getattr(node, 'type', None)
+                self._write(', ')
+            else:
+                self._write(' as ')
+            self.visit(node.name)
+        self._write(':')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+    visit_excepthandler = visit_ExceptHandler
+
+    # TryFinally(stmt* body, stmt* finalbody)
+    def visit_TryFinally(self, node):
+        self._new_line()
+        self._write('try:')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+
+        if getattr(node, 'finalbody', None):
+            self._new_line()
+            self._write('finally:')
+            self._change_indent(1)
+            for statement in node.finalbody:
+                self.visit(statement)
+            self._change_indent(-1)
+
+    # Assert(expr test, expr? msg)
+    def visit_Assert(self, node):
+        self._new_line()
+        self._write('assert ')
+        self.visit(node.test)
+        if getattr(node, 'msg', None):
+            self._write(', ')
+            self.visit(node.msg)
+
+    def visit_alias(self, node):
+        self._write(node.name)
+        if getattr(node, 'asname', None):
+            self._write(' as ')
+            self._write(node.asname)
+
+    # Import(alias* names)
+    def visit_Import(self, node):
+        self._new_line()
+        self._write('import ')
+        self.visit(node.names[0])
+        for name in node.names[1:]:
+            self._write(', ')
+            self.visit(name)
+
+    # ImportFrom(identifier module, alias* names, int? level)
+    def visit_ImportFrom(self, node):
+        self._new_line()
+        self._write('from ')
+        if node.level:
+            self._write('.' * node.level)
+        self._write(node.module)
+        self._write(' import ')
+        self.visit(node.names[0])
+        for name in node.names[1:]:
+            self._write(', ')
+            self.visit(name)
+
+    # Exec(expr body, expr? globals, expr? locals)
+    def visit_Exec(self, node):
+        self._new_line()
+        self._write('exec ')
+        self.visit(node.body)
+        if not node.globals:
+            return
+        self._write(', ')
+        self.visit(node.globals)
+        if not node.locals:
+            return
+        self._write(', ')
+        self.visit(node.locals)
+
+    # Global(identifier* names)
+    def visit_Global(self, node):
+        self._new_line()
+        self._write('global ')
+        self.visit(node.names[0])
+        for name in node.names[1:]:
+            self._write(', ')
+            self.visit(name)
+
+    # Expr(expr value)
+    def visit_Expr(self, node):
+        self._new_line()
+        self.visit(node.value)
+
+    # Pass
+    def visit_Pass(self, node):
+        self._new_line()
+        self._write('pass')
+
+    # Break
+    def visit_Break(self, node):
+        self._new_line()
+        self._write('break')
+
+    # Continue
+    def visit_Continue(self, node):
+        self._new_line()
+        self._write('continue')
+
+    ### EXPRESSIONS
+    def with_parens(f):
+        def _f(self, node):
+            self._write('(')
+            f(self, node)
+            self._write(')')
+        return _f
+
+    bool_operators = {ast.And: 'and', ast.Or: 'or'}
+
+    # BoolOp(boolop op, expr* values)
+    @with_parens
+    def visit_BoolOp(self, node):
+        joiner = ' ' + self.bool_operators[node.op.__class__] + ' '
+        self.visit(node.values[0])
+        for value in node.values[1:]:
+            self._write(joiner)
+            self.visit(value)
+
+    binary_operators = {
+        ast.Add: '+',
+        ast.Sub: '-',
+        ast.Mult: '*',
+        ast.Div: '/',
+        ast.Mod: '%',
+        ast.Pow: '**',
+        ast.LShift: '<<',
+        ast.RShift: '>>',
+        ast.BitOr: '|',
+        ast.BitXor: '^',
+        ast.BitAnd: '&',
+        ast.FloorDiv: '//'
+    }
+
+    # BinOp(expr left, operator op, expr right)
+    @with_parens
+    def visit_BinOp(self, node):
+        self.visit(node.left)
+        self._write(' ' + self.binary_operators[node.op.__class__] + ' ')
+        self.visit(node.right)
+
+    unary_operators = {
+        ast.Invert: '~',
+        ast.Not: 'not',
+        ast.UAdd: '+',
+        ast.USub: '-',
+    }
+
+    # UnaryOp(unaryop op, expr operand)
+    def visit_UnaryOp(self, node):
+        self._write(self.unary_operators[node.op.__class__] + ' ')
+        self.visit(node.operand)
+
+    # Lambda(arguments args, expr body)
+    @with_parens
+    def visit_Lambda(self, node):
+        self._write('lambda ')
+        self.visit(node.args)
+        self._write(': ')
+        self.visit(node.body)
+
+    # IfExp(expr test, expr body, expr orelse)
+    @with_parens
+    def visit_IfExp(self, node):
+        self.visit(node.body)
+        self._write(' if ')
+        self.visit(node.test)
+        self._write(' else ')
+        self.visit(node.orelse)
+
+    # Dict(expr* keys, expr* values)
+    def visit_Dict(self, node):
+        self._write('{')
+        for key, value in zip(node.keys, node.values):
+            self.visit(key)
+            self._write(': ')
+            self.visit(value)
+            self._write(', ')
+        self._write('}')
+
+    def visit_Set(self, node):
+        self._write('{')
+        elts = list(node.elts)
+        last = elts.pop()
+        for elt in elts:
+            self.visit(elt)
+            self._write(', ')
+        self.visit(last)
+        self._write('}')
+
+    # ListComp(expr elt, comprehension* generators)
+    def visit_ListComp(self, node):
+        self._write('[')
+        self.visit(node.elt)
+        for generator in node.generators:
+            # comprehension = (expr target, expr iter, expr* ifs)
+            self._write(' for ')
+            self.visit(generator.target)
+            self._write(' in ')
+            self.visit(generator.iter)
+            for ifexpr in generator.ifs:
+                self._write(' if ')
+                self.visit(ifexpr)
+        self._write(']')
+
+    # GeneratorExp(expr elt, comprehension* generators)
+    def visit_GeneratorExp(self, node):
+        self._write('(')
+        self.visit(node.elt)
+        for generator in node.generators:
+            # comprehension = (expr target, expr iter, expr* ifs)
+            self._write(' for ')
+            self.visit(generator.target)
+            self._write(' in ')
+            self.visit(generator.iter)
+            for ifexpr in generator.ifs:
+                self._write(' if ')
+                self.visit(ifexpr)
+        self._write(')')
+
+    # Yield(expr? value)
+    def visit_Yield(self, node):
+        self._write('yield')
+        if getattr(node, 'value', None):
+            self._write(' ')
+            self.visit(node.value)
+
+    comparison_operators = {
+        ast.Eq: '==',
+        ast.NotEq: '!=',
+        ast.Lt: '<',
+        ast.LtE: '<=',
+        ast.Gt: '>',
+        ast.GtE: '>=',
+        ast.Is: 'is',
+        ast.IsNot: 'is not',
+        ast.In: 'in',
+        ast.NotIn: 'not in',
+    }
+
+    # Compare(expr left, cmpop* ops, expr* comparators)
+    @with_parens
+    def visit_Compare(self, node):
+        self.visit(node.left)
+        for op, comparator in zip(node.ops, node.comparators):
+            self._write(' ' + self.comparison_operators[op.__class__] + ' ')
+            self.visit(comparator)
+
+    # Call(expr func, expr* args, keyword* keywords,
+    #                         expr? starargs, expr? kwargs)
+    def visit_Call(self, node):
+        self.visit(node.func)
+        self._write('(')
+        first = True
+        for arg in node.args:
+            if not first:
+                self._write(', ')
+            first = False
+            self.visit(arg)
+
+        for keyword in node.keywords:
+            if not first:
+                self._write(', ')
+            first = False
+            # keyword = (identifier arg, expr value)
+            self._write(keyword.arg)
+            self._write('=')
+            self.visit(keyword.value)
+        if getattr(node, 'starargs', None):
+            if not first:
+                self._write(', ')
+            first = False
+            self._write('*')
+            self.visit(node.starargs)
+
+        if getattr(node, 'kwargs', None):
+            if not first:
+                self._write(', ')
+            first = False
+            self._write('**')
+            self.visit(node.kwargs)
+        self._write(')')
+
+    # Repr(expr value)
+    def visit_Repr(self, node):
+        self._write('`')
+        self.visit(node.value)
+        self._write('`')
+
+    # Num(object n)
+    def visit_Num(self, node):
+        self._write(repr(node.n))
+
+    # Str(string s)
+    def visit_Str(self, node):
+        self._write(repr(node.s))
+
+    # Attribute(expr value, identifier attr, expr_context ctx)
+    def visit_Attribute(self, node):
+        self.visit(node.value)
+        self._write('.')
+        self._write(node.attr)
+
+    # Subscript(expr value, slice slice, expr_context ctx)
+    def visit_Subscript(self, node):
+        self.visit(node.value)
+        self._write('[')
+
+        def _process_slice(node):
+            if isinstance(node, ast.Ellipsis):
+                self._write('...')
+            elif isinstance(node, ast.Slice):
+                if getattr(node, 'lower', 'None'):
+                    self.visit(node.lower)
+                self._write(':')
+                if getattr(node, 'upper', None):
+                    self.visit(node.upper)
+                if getattr(node, 'step', None):
+                    self._write(':')
+                    self.visit(node.step)
+            elif isinstance(node, ast.Index):
+                self.visit(node.value)
+            elif isinstance(node, ast.ExtSlice):
+                self.visit(node.dims[0])
+                for dim in node.dims[1:]:
+                    self._write(', ')
+                    self.visit(dim)
+            else:
+                raise NotImplemented('Slice type not implemented')
+        _process_slice(node.slice)
+        self._write(']')
+
+    # Name(identifier id, expr_context ctx)
+    def visit_Name(self, node):
+        self._write(node.id)
+
+    # List(expr* elts, expr_context ctx)
+    def visit_List(self, node):
+        self._write('[')
+        for elt in node.elts:
+            self.visit(elt)
+            self._write(', ')
+        self._write(']')
+
+    # Tuple(expr *elts, expr_context ctx)
+    def visit_Tuple(self, node):
+        self._write('(')
+        for elt in node.elts:
+            self.visit(elt)
+            self._write(', ')
+        self._write(')')
+
+
+class AnnotationAwareVisitor(ast.NodeVisitor):
+    def visit(self, node):
+        annotation = node_annotations.get(node)
+        if annotation is not None:
+            assert hasattr(annotation, '_fields')
+            node = annotation
+
+        super(AnnotationAwareVisitor, self).visit(node)
+
+    def apply_transform(self, node):
+        if node not in node_annotations:
+            result = self.transform(node)
+            if result is not None and result is not node:
+                node_annotations[node] = result
+
+
+class NameLookupRewriteVisitor(AnnotationAwareVisitor):
+    def __init__(self, transform):
+        self.transform = transform
+        self.transformed = set()
+        self.scopes = [set()]
+
+    def __call__(self, node):
+        self.visit(node)
+        return self.transformed
+
+    def visit_Name(self, node):
+        scope = self.scopes[-1]
+        if isinstance(node.ctx, ast.Param):
+            scope.add(node.id)
+        elif node.id not in scope:
+            self.transformed.add(node.id)
+            self.apply_transform(node)
+
+    def visit_FunctionDef(self, node):
+        self.scopes[-1].add(node.name)
+
+    def visit_alias(self, node):
+        name = node.asname if node.asname is not None else node.name
+        self.scopes[-1].add(name)
+
+    def visit_Lambda(self, node):
+        self.scopes.append(set())
+        try:
+            self.visit(node.args)
+            self.visit(node.body)
+        finally:
+            self.scopes.pop()
+
+
+class ItemLookupOnAttributeErrorVisitor(AnnotationAwareVisitor):
+    def __init__(self, transform):
+        self.transform = transform
+
+    def visit_Attribute(self, node):
+        self.generic_visit(node)
+        self.apply_transform(node)
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/benchmark.py b/lib3/Chameleon-2.9.2/src/chameleon/benchmark.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/benchmark.py
@@ -0,0 +1,478 @@
+import unittest
+import time
+import os
+import re
+from .utils import text_
+
+re_amp = re.compile(r'&(?!([A-Za-z]+|#[0-9]+);)')
+
+BIGTABLE_ZPT = """\
+<table xmlns="http://www.w3.org/1999/xhtml"
+xmlns:tal="http://xml.zope.org/namespaces/tal">
+<tr tal:repeat="row python: options['table']">
+<td tal:repeat="c python: row.values()">
+<span tal:define="d python: c + 1"
+tal:attributes="class python: 'column-' + str(d)"
+tal:content="python: d" />
+</td>
+</tr>
+</table>"""
+
+MANY_STRINGS_ZPT = """\
+<table xmlns="http://www.w3.org/1999/xhtml"
+xmlns:tal="http://xml.zope.org/namespaces/tal">
+<tr tal:repeat="i python: xrange(1000)">
+<td tal:content="string: number ${i}" />
+</tr>
+</table>
+"""
+
+HELLO_WORLD_ZPT = """\
+<html xmlns="http://www.w3.org/1999/xhtml"
+xmlns:tal="http://xml.zope.org/namespaces/tal">
+<body>
+<h1>Hello, world!</h1>
+</body>
+</html>
+"""
+
+I18N_ZPT = """\
+<html xmlns="http://www.w3.org/1999/xhtml"
+xmlns:tal="http://xml.zope.org/namespaces/tal"
+xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+  <body>
+    <div tal:repeat="i python: xrange(10)">
+      <div i18n:translate="">
+        Hello world!
+      </div>
+      <div i18n:translate="hello_world">
+        Hello world!
+      </div>
+      <div i18n:translate="">
+        <sup>Hello world!</sup>
+      </div>
+    </div>
+  </body>
+</html>
+"""
+
+
+def benchmark(title):
+    def decorator(f):
+        def wrapper(*args):
+            print(
+                "==========================\n " \
+                "%s\n==========================" % \
+                title)
+            return f(*args)
+        return wrapper
+    return decorator
+
+
+def timing(func, *args, **kwargs):
+    t1 = t2 = time.time()
+    i = 0
+    while t2 - t1 < 3:
+        func(**kwargs)
+        func(**kwargs)
+        func(**kwargs)
+        func(**kwargs)
+        i += 4
+        t2 = time.time()
+    return float(10 * (t2 - t1)) / i
+
+
+START = 0
+END = 1
+TAG = 2
+
+
+def yield_tokens(table=None):
+    index = []
+    tag = index.append
+    _re_amp = re_amp
+    tag(START)
+    yield "<", "html", "", ">\n"
+    for r in table:
+        tag(START)
+        yield "<", "tr", "", ">\n"
+
+        for c in r.values():
+            d = c + 1
+            tag(START)
+            yield "<", "td", "", ">\n"
+
+            _tmp5 = d
+            if not isinstance(_tmp5, unicode):
+                _tmp5 = str(_tmp5)
+            if ('&' in _tmp5):
+                if (';' in _tmp5):
+                    _tmp5 = _re_amp.sub('&', _tmp5)
+                else:
+                    _tmp5 = _tmp5.replace('&', '&')
+            if ('<' in _tmp5):
+                _tmp5 = _tmp5.replace('<', '<')
+            if ('>' in _tmp5):
+                _tmp5 = _tmp5.replace('>', '>')
+            if ('"' in _tmp5):
+                _tmp5 = _tmp5.replace('"', '"')
+            _tmp5 = "column-%s" % _tmp5
+
+            _tmp = d
+            if (_tmp.__class__ not in (str, unicode, int, float, )):
+                raise
+            if (_tmp is not None):
+                if not isinstance(_tmp, unicode):
+                    _tmp = str(_tmp)
+                if ('&' in _tmp):
+                    if (';' in _tmp):
+                        _tmp = _re_amp.sub('&', _tmp)
+                    else:
+                        _tmp = _tmp.replace('&', '&')
+                if ('<' in _tmp):
+                    _tmp = _tmp.replace('<', '<')
+                if ('>' in _tmp):
+                    _tmp = _tmp.replace('>', '>')
+            tag(START)
+
+            t = ["classicism"]
+
+            yield "<", "span", " ", t[0], '="', _tmp5, '"', ">\n"
+            tag(END)
+            yield "</", "span", ">\n"
+            tag(END)
+            yield "</", "td", ">\n"
+        tag(END)
+        yield "</", "tr", ">\n"
+    tag(END)
+    yield "</", "html", ">\n"
+
+
+def yield_tokens_dict_version(**kwargs):
+    index = []
+    tag = index.append
+    _re_amp = re_amp
+    tag(START)
+    yield "<", "html", "", ">\n"
+
+    for r in kwargs['table']:
+        kwargs['r'] = r
+        tag(START)
+        yield "<", "tr", "", ">\n"
+
+        for c in kwargs['r'].values():
+            kwargs['d'] = c + 1
+            tag(START)
+            yield "<", "td", "", ">\n"
+
+            _tmp5 = kwargs['d']
+            if not isinstance(_tmp5, unicode):
+                _tmp5 = str(_tmp5)
+            if ('&' in _tmp5):
+                if (';' in _tmp5):
+                    _tmp5 = _re_amp.sub('&', _tmp5)
+                else:
+                    _tmp5 = _tmp5.replace('&', '&')
+            if ('<' in _tmp5):
+                _tmp5 = _tmp5.replace('<', '<')
+            if ('>' in _tmp5):
+                _tmp5 = _tmp5.replace('>', '>')
+            if ('"' in _tmp5):
+                _tmp5 = _tmp5.replace('"', '"')
+            _tmp5 = "column-%s" % _tmp5
+
+            _tmp = kwargs['d']
+            if (_tmp.__class__ not in (str, unicode, int, float, )):
+                raise
+            if (_tmp is not None):
+                if not isinstance(_tmp, unicode):
+                    _tmp = str(_tmp)
+                if ('&' in _tmp):
+                    if (';' in _tmp):
+                        _tmp = _re_amp.sub('&', _tmp)
+                    else:
+                        _tmp = _tmp.replace('&', '&')
+                if ('<' in _tmp):
+                    _tmp = _tmp.replace('<', '<')
+                if ('>' in _tmp):
+                    _tmp = _tmp.replace('>', '>')
+            tag(START)
+
+            t = ["classicism"]
+
+            yield "<", "span", " ", t[0], '="', _tmp5, '"', ">\n"
+            tag(END)
+            yield "</", "span", ">\n"
+            tag(END)
+            yield "</", "td", ">\n"
+        tag(END)
+        yield "</", "tr", ">\n"
+    tag(END)
+    yield "</", "html", ">\n"
+
+
+def yield_stream(table=None):
+    _re_amp = re_amp
+    yield START, ("html", "", "\n"), None
+    for r in table:
+        yield START, ("tr", "", "\n"), None
+
+        for c in r.values():
+            d = c + 1
+            yield START, ("td", "", "\n"), None
+
+            _tmp5 = d
+            if not isinstance(_tmp5, unicode):
+                _tmp5 = str(_tmp5)
+            if ('&' in _tmp5):
+                if (';' in _tmp5):
+                    _tmp5 = _re_amp.sub('&', _tmp5)
+                else:
+                    _tmp5 = _tmp5.replace('&', '&')
+            if ('<' in _tmp5):
+                _tmp5 = _tmp5.replace('<', '<')
+            if ('>' in _tmp5):
+                _tmp5 = _tmp5.replace('>', '>')
+            if ('"' in _tmp5):
+                _tmp5 = _tmp5.replace('"', '"')
+            _tmp5 = "column-%s" % _tmp5
+
+            _tmp = d
+            if (_tmp.__class__ not in (str, unicode, int, float, )):
+                raise
+            if (_tmp is not None):
+                if not isinstance(_tmp, unicode):
+                    _tmp = str(_tmp)
+                if ('&' in _tmp):
+                    if (';' in _tmp):
+                        _tmp = _re_amp.sub('&', _tmp)
+                    else:
+                        _tmp = _tmp.replace('&', '&')
+                if ('<' in _tmp):
+                    _tmp = _tmp.replace('<', '<')
+                if ('>' in _tmp):
+                    _tmp = _tmp.replace('>', '>')
+            yield START, ("span", "", _tmp, " ", "class", _tmp5), None
+
+            yield END, ("span", "", "\n"), None
+            yield END, ("td", "", "\n"), None
+        yield END, ("tr", "", "\n"), None
+    yield END, ("html", "", "\n"), None
+
+from itertools import chain
+
+
+def bigtable_python_tokens(table=None, renderer=None):
+    iterable = renderer(table=table)
+    stream = chain(*iterable)
+    return "".join(stream)
+
+
+def bigtable_python_stream(table=None, renderer=None):
+    stream = renderer(table=table)
+    return "".join(stream_output(stream))
+
+
+def bigtable_python_stream_with_filter(table=None, renderer=None):
+    stream = renderer(table=table)
+    return "".join(stream_output(uppercase_filter(stream)))
+
+
+def uppercase_filter(stream):
+    for kind, data, pos in stream:
+        if kind is START:
+            data = (data[0], data[1], data[2].upper(),) + data[3:]
+        elif kind is END:
+            data = (data[0], data[1], data[2].upper())
+        elif kind is TAG:
+            raise NotImplemented
+        yield kind, data, pos
+
+
+def stream_output(stream):
+    for kind, data, pos in stream:
+        if kind is START:
+            tag = data[0]
+            yield "<%s" % tag
+            l = len(data)
+
+            # optimize for common cases
+            if l == 3:
+                pass
+            elif l == 6:
+                yield '%s%s="%s"' % (data[3], data[4], data[5])
+            else:
+                i = 3
+                while i < l:
+                    yield '%s%s="%s"' % (data[i], data[i + 1], data[i + 2])
+                    i += 3
+            yield "%s>%s" % (data[1], data[2])
+        elif kind is END:
+            yield "</%s%s>%s" % data
+        elif kind is TAG:
+            raise NotImplemented
+
+
+class Benchmarks(unittest.TestCase):
+    table = [dict(a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8, i=9, j=10) \
+             for x in range(1000)]
+
+    def setUp(self):
+        # set up i18n component
+        from zope.i18n import translate
+        from zope.i18n.interfaces import INegotiator
+        from zope.i18n.interfaces import ITranslationDomain
+        from zope.i18n.negotiator import Negotiator
+        from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
+        from zope.i18n.tests.test_negotiator import Env
+        from zope.tales.tales import Context
+
+        self.env = Env(('klingon', 'da', 'en', 'fr', 'no'))
+
+        class ZopeI18NContext(Context):
+
+            def translate(self, msgid, domain=None, context=None,
+                          mapping=None, default=None):
+                context = self.vars['options']['env']
+                return translate(msgid, domain, mapping,
+                                 context=context, default=default)
+
+        def _getContext(self, contexts=None, **kwcontexts):
+            if contexts is not None:
+                if kwcontexts:
+                    kwcontexts.update(contexts)
+                else:
+                    kwcontexts = contexts
+            return ZopeI18NContext(self, kwcontexts)
+
+        def _pt_getEngineContext(namespace):
+            self = namespace['template']
+            engine = self.pt_getEngine()
+            return _getContext(engine, namespace)
+
+        import zope.component
+        zope.component.provideUtility(Negotiator(), INegotiator)
+        catalog = SimpleTranslationDomain('domain')
+        zope.component.provideUtility(catalog, ITranslationDomain, 'domain')
+        self.files = os.path.abspath(os.path.join(__file__, '..', 'input'))
+
+    @staticmethod
+    def _chameleon(body, **kwargs):
+        from .zpt.template import PageTemplate
+        return PageTemplate(body, **kwargs)
+
+    @staticmethod
+    def _zope(body):
+        from zope.pagetemplate.pagetemplatefile import PageTemplate
+        template = PageTemplate()
+        template.pt_edit(body, 'text/xhtml')
+        return template
+
+    @benchmark(text_("BIGTABLE [python]"))
+    def test_bigtable(self):
+        options = {'table': self.table}
+
+        t_chameleon = timing(self._chameleon(BIGTABLE_ZPT), options=options)
+        print("chameleon:         %7.2f" % t_chameleon)
+
+        t_chameleon_utf8 = timing(
+            self._chameleon(BIGTABLE_ZPT, encoding='utf-8'), options=options)
+        print("chameleon (utf-8): %7.2f" % t_chameleon_utf8)
+
+        t_tokens = timing(
+            bigtable_python_tokens, table=self.table, renderer=yield_tokens)
+        print("token:             %7.2f" % t_tokens)
+
+        t_tokens_dict_version = timing(
+            bigtable_python_tokens, table=self.table,
+            renderer=yield_tokens_dict_version)
+        print("token (dict):      %7.2f" % t_tokens_dict_version)
+
+        t_stream = timing(
+            bigtable_python_stream, table=self.table, renderer=yield_stream)
+        print("stream:            %7.2f" % t_stream)
+
+        t_zope = timing(self._zope(BIGTABLE_ZPT), table=self.table)
+        print("zope.pagetemplate: %7.2f" % t_zope)
+        print("                  %7.1fX" % (t_zope / t_chameleon))
+
+        print("--------------------------")
+        print("check: %d vs %d" % (
+            len(self._chameleon(BIGTABLE_ZPT)(options=options)),
+            len(self._zope(BIGTABLE_ZPT)(table=self.table))))
+        print("--------------------------")
+
+    @benchmark(text_("MANY STRINGS [python]"))
+    def test_many_strings(self):
+        t_chameleon = timing(self._chameleon(MANY_STRINGS_ZPT))
+        print("chameleon:         %7.2f" % t_chameleon)
+        t_zope = timing(self._zope(MANY_STRINGS_ZPT))
+        print("zope.pagetemplate: %7.2f" % t_zope)
+        print("                  %7.1fX" % (t_zope / t_chameleon))
+
+        print("--------------------------")
+        print("check: %d vs %d" % (
+            len(self._chameleon(MANY_STRINGS_ZPT)()),
+            len(self._zope(MANY_STRINGS_ZPT)())))
+        print("--------------------------")
+
+    @benchmark(text_("HELLO WORLD"))
+    def test_hello_world(self):
+        t_chameleon = timing(self._chameleon(HELLO_WORLD_ZPT)) * 1000
+        print("chameleon:         %7.2f" % t_chameleon)
+        t_zope = timing(self._zope(HELLO_WORLD_ZPT)) * 1000
+        print("zope.pagetemplate: %7.2f" % t_zope)
+        print("                  %7.1fX" % (t_zope / t_chameleon))
+
+        print("--------------------------")
+        print("check: %d vs %d" % (
+            len(self._chameleon(HELLO_WORLD_ZPT)()),
+            len(self._zope(HELLO_WORLD_ZPT)())))
+        print("--------------------------")
+
+    @benchmark(text_("I18N"))
+    def test_i18n(self):
+        from zope.i18n import translate
+        t_chameleon = timing(
+            self._chameleon(I18N_ZPT),
+            translate=translate,
+            language="klingon") * 1000
+        print("chameleon:         %7.2f" % t_chameleon)
+        t_zope = timing(self._zope(I18N_ZPT), env=self.env) * 1000
+        print("zope.pagetemplate: %7.2f" % t_zope)
+        print("                  %7.1fX" % (t_zope / t_chameleon))
+
+    @benchmark(text_("COMPILATION"))
+    def test_compilation(self):
+        template = self._chameleon(HELLO_WORLD_ZPT)
+
+        def chameleon_cook_and_render(template=template):
+            template.cook(HELLO_WORLD_ZPT)
+            template()
+
+        t_chameleon = timing(chameleon_cook_and_render) * 1000
+        print("chameleon:         %7.2f" % t_chameleon)
+
+        template = self._zope(HELLO_WORLD_ZPT)
+
+        def zope_cook_and_render(templte=template):
+            template._cook()
+            template()
+
+        t_zope = timing(zope_cook_and_render) * 1000
+        print("zope.pagetemplate: %7.2f" % t_zope)
+        print("                    %0.3fX" % (t_zope / t_chameleon))
+
+
+def start():
+    result = unittest.TestResult()
+    test = unittest.makeSuite(Benchmarks)
+    test.run(result)
+
+    for error in result.errors:
+        print("Error in %s...\n" % error[0])
+        print(error[1])
+
+    for failure in result.failures:
+        print("Failure in %s...\n" % failure[0])
+        print(failure[1])
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/codegen.py b/lib3/Chameleon-2.9.2/src/chameleon/codegen.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/codegen.py
@@ -0,0 +1,221 @@
+try:
+    import ast
+except ImportError:
+    from chameleon import ast24 as ast
+
+import inspect
+import textwrap
+import types
+import copy
+
+try:
+    import __builtin__ as builtins
+except ImportError:
+    import builtins
+
+reverse_builtin_map = {}
+for name, value in builtins.__dict__.items():
+    try:
+        hash(value)
+    except TypeError:
+        continue
+
+    reverse_builtin_map[value] = name
+
+try:
+    basestring
+except NameError:
+    basestring = str
+
+from .astutil import ASTCodeGenerator
+from .astutil import load
+from .astutil import store
+from .astutil import parse
+from .astutil import Builtin
+from .astutil import Symbol
+from .astutil import node_annotations
+
+from .exc import CompilationError
+
+
+try:
+    NATIVE_NUMBERS = int, float, long, bool
+except NameError:
+    NATIVE_NUMBERS = int, float, bool
+
+
+def template(function, mode='exec', **kw):
+    def wrapper(*vargs, **kwargs):
+        symbols = dict(zip(args, vargs + defaults))
+        symbols.update(kwargs)
+
+        class Visitor(ast.NodeVisitor):
+            def visit_Name(self, node):
+                value = symbols.get(node.id, self)
+                if value is not self:
+                    if isinstance(value, basestring):
+                        value = load(value)
+                    if isinstance(value, type) or value in reverse_builtin_map:
+                        name = reverse_builtin_map.get(value)
+                        if name is not None:
+                            value = Builtin(name)
+                        else:
+                            value = Symbol(value)
+
+                    assert node not in node_annotations
+                    assert hasattr(value, '_fields')
+                    node_annotations[node] = value
+
+        expr = parse(source, mode=mode)
+        if not isinstance(function, basestring):
+            expr = expr.body[0]
+
+        Visitor().visit(expr)
+        return expr.body
+
+    if isinstance(function, basestring):
+        source = function
+        defaults = args = ()
+        return wrapper(**kw)
+
+    source = textwrap.dedent(inspect.getsource(function))
+    argspec = inspect.getargspec(function)
+    args = argspec[0]
+    defaults = argspec[3] or ()
+    return wrapper
+
+
+class TemplateCodeGenerator(ASTCodeGenerator):
+    """Extends the standard Python code generator class with handlers
+    for the helper node classes:
+
+    - Symbol (an importable value)
+    - Static (value that can be made global)
+    - Builtin (from the builtins module)
+    - Marker (short-hand for a unique static object)
+
+    """
+
+    names = ()
+
+    def __init__(self, tree):
+        self.imports = {}
+        self.defines = {}
+        self.markers = {}
+
+        # Generate code
+        super(TemplateCodeGenerator, self).__init__(tree)
+
+    def visit_Module(self, node):
+        super(TemplateCodeGenerator, self).visit_Module(node)
+
+        # Make sure we terminate the line printer
+        self.flush()
+
+        # Clear lines array for import visits
+        body = self.lines
+        self.lines = []
+
+        while self.defines:
+            name, node = self.defines.popitem()
+            assignment = ast.Assign(targets=[store(name)], value=node)
+            self.visit(assignment)
+
+        # Make sure we terminate the line printer
+        self.flush()
+
+        # Clear lines array for import visits
+        defines = self.lines
+        self.lines = []
+
+        while self.imports:
+            value, node = self.imports.popitem()
+
+            if isinstance(value, types.ModuleType):
+                stmt = ast.Import(
+                    names=[ast.alias(name=value.__name__, asname=node.id)])
+            elif hasattr(value, '__name__'):
+                path = reverse_builtin_map.get(value)
+                if path is None:
+                    path = value.__module__
+                    name = value.__name__
+                stmt = ast.ImportFrom(
+                    module=path,
+                    names=[ast.alias(name=name, asname=node.id)],
+                    level=0,
+                )
+            else:
+                raise TypeError(value)
+
+            self.visit(stmt)
+
+        # Clear last import
+        self.flush()
+
+        # Stich together lines
+        self.lines += defines + body
+
+    def define(self, name, node):
+        assert node is not None
+        value = self.defines.get(name)
+
+        if value is node:
+            pass
+        elif value is None:
+            self.defines[name] = node
+        else:
+            raise CompilationError(
+                "Duplicate symbol name for define.", name)
+
+        return load(name)
+
+    def require(self, value):
+        if value is None:
+            return load("None")
+
+        if isinstance(value, NATIVE_NUMBERS):
+            return ast.Num(value)
+
+        node = self.imports.get(value)
+        if node is None:
+            # we come up with a unique symbol based on the class name
+            name = "_%s" % getattr(value, '__name__', str(value)).\
+                   rsplit('.', 1)[-1]
+            node = load(name)
+            self.imports[value] = store(node.id)
+
+        return node
+
+    def visit(self, node):
+        annotation = node_annotations.get(node)
+        if annotation is None:
+            super(TemplateCodeGenerator, self).visit(node)
+        else:
+            self.visit(annotation)
+
+    def visit_Comment(self, node):
+        if node.stmt is None:
+            self._new_line()
+        else:
+            self.visit(node.stmt)
+
+        for line in node.text.replace('\r', '\n').split('\n'):
+            self._new_line()
+            self._write("%s#%s" % (node.space, line))
+
+    def visit_Builtin(self, node):
+        name = load(node.id)
+        self.visit(name)
+
+    def visit_Symbol(self, node):
+        node = self.require(node.value)
+        self.visit(node)
+
+    def visit_Static(self, node):
+        if node.name is None:
+            name = "_static_%d" % id(node.value)
+        else:
+            name = node.name
+
+        node = self.define(name, node.value)
+        self.visit(node)
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/compiler.py b/lib3/Chameleon-2.9.2/src/chameleon/compiler.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/compiler.py
@@ -0,0 +1,1553 @@
+import re
+import sys
+import itertools
+import logging
+import threading
+import functools
+import collections
+import pickle
+import textwrap
+
+from .astutil import load
+from .astutil import store
+from .astutil import param
+from .astutil import swap
+from .astutil import subscript
+from .astutil import node_annotations
+from .astutil import annotated
+from .astutil import NameLookupRewriteVisitor
+from .astutil import Comment
+from .astutil import Symbol
+from .astutil import Builtin
+
+from .codegen import TemplateCodeGenerator
+from .codegen import template
+
+from .tal import ErrorInfo
+from .tal import NAME
+from .i18n import fast_translate
+
+from .nodes import Text
+from .nodes import Value
+from .nodes import Substitution
+from .nodes import Assignment
+from .nodes import Module
+from .nodes import Context
+
+from .tokenize import Token
+from .config import DEBUG_MODE
+from .exc import TranslationError
+from .exc import ExpressionError
+from .parser import groupdict
+
+from .utils import DebuggingOutputStream
+from .utils import char2entity
+from .utils import ListDictProxy
+from .utils import native_string
+from .utils import byte_string
+from .utils import string_type
+from .utils import unicode_string
+from .utils import version
+from .utils import ast
+from .utils import safe_native
+from .utils import builtins
+from .utils import decode_htmlentities
+
+
+if version >= (3, 0, 0):
+    long = int
+
+log = logging.getLogger('chameleon.compiler')
+
+COMPILER_INTERNALS_OR_DISALLOWED = set([
+    "econtext",
+    "rcontext",
+    "str",
+    "int",
+    "float",
+    "long",
+    "len",
+    "None",
+    "True",
+    "False",
+    "RuntimeError",
+    ])
+
+
+RE_MANGLE = re.compile('[^\w_]')
+RE_NAME = re.compile('^%s$' % NAME)
+
+if DEBUG_MODE:
+    LIST = template("cls()", cls=DebuggingOutputStream, mode="eval")
+else:
+    LIST = template("[]", mode="eval")
+
+
+def identifier(prefix, suffix=None):
+    return "__%s_%s" % (prefix, mangle(suffix or id(prefix)))
+
+
+def mangle(string):
+    return RE_MANGLE.sub('_', str(string)).replace('\n', '')
+
+
+def load_econtext(name):
+    return template("getitem(KEY)", KEY=ast.Str(s=name), mode="eval")
+
+
+def store_econtext(name):
+    name = native_string(name)
+    return subscript(name, load("econtext"), ast.Store())
+
+
+def store_rcontext(name):
+    name = native_string(name)
+    return subscript(name, load("rcontext"), ast.Store())
+
+
+def set_error(token, exception):
+    try:
+        line, column = token.location
+        filename = token.filename
+    except AttributeError:
+        line, column = 0, 0
+        filename = "<string>"
+
+    string = safe_native(token)
+
+    return template(
+        "rcontext.setdefault('__error__', [])."
+        "append((string, line, col, src, exc))",
+        string=ast.Str(s=string),
+        line=ast.Num(n=line),
+        col=ast.Num(n=column),
+        src=ast.Str(s=filename),
+        sys=Symbol(sys),
+        exc=exception,
+        )
+
+
+def try_except_wrap(stmts, token):
+    exception = template(
+        "exc_info()[1]", exc_info=Symbol(sys.exc_info), mode="eval"
+        )
+
+    body = set_error(token, exception) + template("raise")
+
+    return ast.TryExcept(
+        body=stmts,
+        handlers=[ast.ExceptHandler(body=body)],
+        )
+
+
+ at template
+def emit_node(node):  # pragma: no cover
+    __append(node)
+
+
+ at template
+def emit_node_if_non_trivial(node):  # pragma: no cover
+    if node is not None:
+        __append(node)
+
+
+ at template
+def emit_bool(target, s, default_marker=None,
+                 default=None):  # pragma: no cover
+    if target is default_marker:
+        target = default
+    elif target:
+        target = s
+    else:
+        target = None
+
+
+ at template
+def emit_convert(
+    target, encoded=byte_string, str=unicode_string,
+    long=long, type=type,
+    default_marker=None, default=None):  # pragma: no cover
+    if target is None:
+        pass
+    elif target is default_marker:
+        target = default
+    else:
+        __tt = type(target)
+
+        if __tt is int or __tt is float or __tt is long:
+            target = str(target)
+        elif __tt is encoded:
+            target = decode(target)
+        elif __tt is not str:
+            try:
+                target = target.__html__
+            except AttributeError:
+                __converted = convert(target)
+                target = str(target) if target is __converted else __converted
+            else:
+                target = target()
+
+
+ at template
+def emit_translate(target, msgid, default=None):  # pragma: no cover
+    target = translate(msgid, default=default, domain=__i18n_domain)
+
+
+ at template
+def emit_convert_and_escape(
+    target, quote=None, quote_entity=None, str=unicode_string, long=long,
+    type=type, encoded=byte_string,
+    default_marker=None, default=None):  # pragma: no cover
+    if target is None:
+        pass
+    elif target is default_marker:
+        target = default
+    else:
+        __tt = type(target)
+
+        if __tt is int or __tt is float or __tt is long:
+            target = str(target)
+        else:
+            try:
+                if __tt is encoded:
+                    target = decode(target)
+                elif __tt is not str:
+                    try:
+                        target = target.__html__
+                    except:
+                        __converted = convert(target)
+                        target = str(target) if target is __converted \
+                                 else __converted
+                    else:
+                        raise RuntimeError
+            except RuntimeError:
+                target = target()
+            else:
+                if target is not None:
+                    try:
+                        escape = __re_needs_escape(target) is not None
+                    except TypeError:
+                        pass
+                    else:
+                        if escape:
+                            # Character escape
+                            if '&' in target:
+                                target = target.replace('&', '&')
+                            if '<' in target:
+                                target = target.replace('<', '<')
+                            if '>' in target:
+                                target = target.replace('>', '>')
+                            if quote is not None and quote in target:
+                                target = target.replace(quote, quote_entity)
+
+
+class Interpolator(object):
+    braces_required_regex = re.compile(
+        r'(?<!\\)\$({(?P<expression>.*)})',
+        re.DOTALL)
+
+    braces_optional_regex = re.compile(
+        r'(?<!\\)\$({(?P<expression>.*)}|(?P<variable>[A-Za-z][A-Za-z0-9_]*))',
+        re.DOTALL)
+
+    def __init__(self, expression, braces_required, translate=False):
+        self.expression = expression
+        self.regex = self.braces_required_regex if braces_required else \
+                     self.braces_optional_regex
+        self.translate = translate
+
+    def __call__(self, name, engine):
+        """The strategy is to find possible expression strings and
+        call the ``validate`` function of the parser to validate.
+
+        For every possible starting point, the longest possible
+        expression is tried first, then the second longest and so
+        forth.
+
+        Example 1:
+
+          ${'expressions use the ${<expression>} format'}
+
+        The entire expression is attempted first and it is also the
+        only one that validates.
+
+        Example 2:
+
+          ${'Hello'} ${'world!'}
+
+        Validation of the longest possible expression (the entire
+        string) will fail, while the second round of attempts,
+        ``${'Hello'}`` and ``${'world!'}`` respectively, validate.
+
+        """
+
+        body = []
+        nodes = []
+        text = self.expression
+
+        expr_map = {}
+        translate = self.translate
+
+        while text:
+            matched = text
+            m = self.regex.search(matched)
+            if m is None:
+                nodes.append(ast.Str(s=text))
+                break
+
+            part = text[:m.start()]
+            text = text[m.start():]
+
+            if part:
+                node = ast.Str(s=part)
+                nodes.append(node)
+
+            if not body:
+                target = name
+            else:
+                target = store("%s_%d" % (name.id, text.pos))
+
+            while True:
+                d = groupdict(m, matched)
+                string = d["expression"] or d["variable"] or ""
+
+                string = decode_htmlentities(string)
+
+                try:
+                    compiler = engine.parse(string)
+                    body += compiler.assign_text(target)
+                except ExpressionError:
+                    matched = matched[m.start():m.end() - 1]
+                    m = self.regex.search(matched)
+                    if m is None:
+                        raise
+                else:
+                    break
+
+            # If one or more expressions are not simple names, we
+            # disable translation.
+            if RE_NAME.match(string) is None:
+                translate = False
+
+            # if this is the first expression, use the provided
+            # assignment name; otherwise, generate one (here based
+            # on the string position)
+            node = load(target.id)
+            nodes.append(node)
+
+            expr_map[node] = safe_native(string)
+
+            text = text[len(m.group()):]
+
+        if len(nodes) == 1:
+            target = nodes[0]
+
+            if translate and isinstance(target, ast.Str):
+                target = template(
+                    "translate(msgid, domain=__i18n_domain, context=econtext)",
+                    msgid=target, mode="eval",
+                    )
+        else:
+            if translate:
+                formatting_string = ""
+                keys = []
+                values = []
+
+                for node in nodes:
+                    if isinstance(node, ast.Str):
+                        formatting_string += node.s
+                    else:
+                        string = expr_map[node]
+                        formatting_string += "${%s}" % string
+                        keys.append(ast.Str(s=string))
+                        values.append(node)
+
+                target = template(
+                    "translate(msgid, mapping=mapping, domain=__i18n_domain, context=econtext)",
+                    msgid=ast.Str(s=formatting_string),
+                    mapping=ast.Dict(keys=keys, values=values),
+                    mode="eval"
+                    )
+            else:
+                nodes = [
+                    template(
+                        "NODE if NODE is not None else ''",
+                        NODE=node, mode="eval"
+                        )
+                    for node in nodes
+                    ]
+
+                target = ast.BinOp(
+                    left=ast.Str(s="%s" * len(nodes)),
+                    op=ast.Mod(),
+                    right=ast.Tuple(elts=nodes, ctx=ast.Load()))
+
+        body += [ast.Assign(targets=[name], value=target)]
+        return body
+
+
+class ExpressionEngine(object):
+    """Expression engine.
+
+    This test demonstrates how to configure and invoke the engine.
+
+    >>> from chameleon import tales
+    >>> parser = tales.ExpressionParser({
+    ...     'python': tales.PythonExpr,
+    ...     'not': tales.NotExpr,
+    ...     'exists': tales.ExistsExpr,
+    ...     'string': tales.StringExpr,
+    ...     }, 'python')
+
+    >>> engine = ExpressionEngine(parser)
+
+    An expression evaluation function:
+
+    >>> eval = lambda expression: tales.test(
+    ...     tales.IdentityExpr(expression), engine)
+
+    We have provided 'python' as the default expression type. This
+    means that when no prefix is given, the expression is evaluated as
+    a Python expression:
+
+    >>> eval('not False')
+    True
+
+    Note that the ``type`` prefixes bind left. If ``not`` and
+    ``exits`` are two expression type prefixes, consider the
+    following::
+
+    >>> eval('not: exists: int(None)')
+    True
+
+    The pipe operator binds right. In the following example, but
+    arguments are evaluated against ``not: exists: ``.
+
+    >>> eval('not: exists: help')
+    False
+
+    >>> eval('string:test ${1}${2}')
+    'test 12'
+
+    """
+
+    supported_char_escape_set = set(('&', '<', '>'))
+
+    def __init__(self, parser, char_escape=(),
+                 default=None, default_marker=None):
+        self._parser = parser
+        self._char_escape = char_escape
+        self._default = default
+        self._default_marker = default_marker
+
+    def __call__(self, string, target):
+        # BBB: This method is deprecated. Instead, a call should first
+        # be made to ``parse`` and then one of the assignment methods
+        # ("value" or "text").
+
+        compiler = self.parse(string)
+        return compiler(string, target)
+
+    def parse(self, string):
+        expression = self._parser(string)
+        compiler = self.get_compiler(expression, string)
+        return ExpressionCompiler(compiler, self)
+
+    def get_compiler(self, expression, string):
+        def compiler(target, engine, result_type=None, *args):
+            stmts = expression(target, engine)
+
+            if result_type is not None:
+                method = getattr(self, '_convert_%s' % result_type)
+                steps = method(target, *args)
+                stmts.extend(steps)
+
+            return [try_except_wrap(stmts, string)]
+
+        return compiler
+
+    def _convert_bool(self, target, s):
+        """Converts value given by ``target`` to a string ``s`` if the
+        target is a true value, otherwise ``None``.
+        """
+
+        return emit_bool(
+            target, ast.Str(s=s),
+            default=self._default,
+            default_marker=self._default_marker
+            )
+
+    def _convert_text(self, target):
+        """Converts value given by ``target`` to text."""
+
+        if self._char_escape:
+            # This is a cop-out - we really only support a very select
+            # set of escape characters
+            other = set(self._char_escape) - self.supported_char_escape_set
+
+            if other:
+                for supported in '"', '\'', '':
+                    if supported in self._char_escape:
+                        quote = supported
+                        break
+                else:
+                    raise RuntimeError(
+                        "Unsupported escape set: %s." % repr(self._char_escape)
+                        )
+            else:
+                quote = '\0'
+
+            entity = char2entity(quote or '\0')
+
+            return emit_convert_and_escape(
+                target,
+                quote=ast.Str(s=quote),
+                quote_entity=ast.Str(s=entity),
+                default=self._default,
+                default_marker=self._default_marker,
+                )
+
+        return emit_convert(
+            target,
+            default=self._default,
+            default_marker=self._default_marker,
+            )
+
+
+class ExpressionCompiler(object):
+    def __init__(self, compiler, engine):
+        self.compiler = compiler
+        self.engine = engine
+
+    def assign_bool(self, target, s):
+        return self.compiler(target, self.engine, "bool", s)
+
+    def assign_text(self, target):
+        return self.compiler(target, self.engine, "text")
+
+    def assign_value(self, target):
+        return self.compiler(target, self.engine)
+
+
+class ExpressionEvaluator(object):
+    """Evaluates dynamic expression.
+
+    This is not particularly efficient, but supported for legacy
+    applications.
+
+    >>> from chameleon import tales
+    >>> parser = tales.ExpressionParser({'python': tales.PythonExpr}, 'python')
+    >>> engine = functools.partial(ExpressionEngine, parser)
+
+    >>> evaluate = ExpressionEvaluator(engine, {
+    ...     'foo': 'bar',
+    ...     })
+
+    The evaluation function is passed the local and remote context,
+    the expression type and finally the expression.
+
+    >>> evaluate({'boo': 'baz'}, {}, 'python', 'foo + boo')
+    'barbaz'
+
+    The cache is now primed:
+
+    >>> evaluate({'boo': 'baz'}, {}, 'python', 'foo + boo')
+    'barbaz'
+
+    Note that the call method supports currying of the expression
+    argument:
+
+    >>> python = evaluate({'boo': 'baz'}, {}, 'python')
+    >>> python('foo + boo')
+    'barbaz'
+
+    """
+
+    __slots__ = "_engine", "_cache", "_names", "_builtins"
+
+    def __init__(self, engine, builtins):
+        self._engine = engine
+        self._names, self._builtins = zip(*builtins.items())
+        self._cache = {}
+
+    def __call__(self, econtext, rcontext, expression_type, string=None):
+        if string is None:
+            return functools.partial(
+                self.__call__, econtext, rcontext, expression_type
+                )
+
+        expression = "%s:%s" % (expression_type, string)
+
+        try:
+            evaluate = self._cache[expression]
+        except KeyError:
+            assignment = Assignment(["_result"], expression, True)
+            module = Module("evaluate", Context(assignment))
+
+            compiler = Compiler(
+                self._engine, module, ('econtext', 'rcontext') + self._names
+                )
+
+            env = {}
+            exec(compiler.code, env)
+            evaluate = self._cache[expression] = env["evaluate"]
+
+        evaluate(econtext, rcontext, *self._builtins)
+        return econtext['_result']
+
+
+class NameTransform(object):
+    """
+    >>> nt = NameTransform(
+    ...     set(('foo', 'bar', )), {'boo': 'boz'},
+    ...     ('econtext', ),
+    ... )
+
+    >>> def test(node):
+    ...     rewritten = nt(node)
+    ...     module = ast.Module([ast.fix_missing_locations(rewritten)])
+    ...     codegen = TemplateCodeGenerator(module)
+    ...     return codegen.code
+
+    Any odd name:
+
+    >>> test(load('frobnitz'))
+    "getitem('frobnitz')"
+
+    A 'builtin' name will first be looked up via ``get`` allowing fall
+    back to the global builtin value:
+
+    >>> test(load('foo'))
+    "get('foo', foo)"
+
+    Internal names (with two leading underscores) are left alone:
+
+    >>> test(load('__internal'))
+    '__internal'
+
+    Compiler internals or disallowed names:
+
+    >>> test(load('econtext'))
+    'econtext'
+
+    Aliased names:
+
+    >>> test(load('boo'))
+    'boz'
+
+    """
+
+    def __init__(self, builtins, aliases, internals):
+        self.builtins = builtins
+        self.aliases = aliases
+        self.internals = internals
+
+    def __call__(self, node):
+        name = node.id
+
+        # Don't rewrite names that begin with an underscore; they are
+        # internal and can be assumed to be locally defined. This
+        # policy really should be part of the template program, not
+        # defined here in the compiler.
+        if name.startswith('__') or name in self.internals:
+            return node
+
+        if isinstance(node.ctx, ast.Store):
+            return store_econtext(name)
+
+        aliased = self.aliases.get(name)
+        if aliased is not None:
+            return load(aliased)
+
+        # If the name is a Python global, first try acquiring it from
+        # the dynamic context, then fall back to the global.
+        if name in self.builtins:
+            return template(
+                "get(key, name)",
+                mode="eval",
+                key=ast.Str(s=name),
+                name=load(name),
+                )
+
+        # Otherwise, simply acquire it from the dynamic context.
+        return load_econtext(name)
+
+
+class ExpressionTransform(object):
+    """Internal wrapper to transform expression nodes into assignment
+    statements.
+
+    The node input may use the provided expression engine, but other
+    expression node types are supported such as ``Builtin`` which
+    simply resolves a built-in name.
+
+    Used internally be the compiler.
+    """
+
+    loads_symbol = Symbol(pickle.loads)
+
+    def __init__(self, engine_factory, cache, visitor, strict=True):
+        self.engine_factory = engine_factory
+        self.cache = cache
+        self.strict = strict
+        self.visitor = visitor
+
+    def __call__(self, expression, target):
+        if isinstance(target, string_type):
+            target = store(target)
+
+        try:
+            stmts = self.translate(expression, target)
+        except ExpressionError:
+            if self.strict:
+                raise
+
+            exc = sys.exc_info()[1]
+            p = pickle.dumps(exc)
+
+            stmts = template(
+                "__exc = loads(p)", loads=self.loads_symbol, p=ast.Str(s=p)
+                )
+
+            token = Token(exc.token, exc.offset, filename=exc.filename)
+
+            stmts += set_error(token, load("__exc"))
+            stmts += [ast.Raise(exc=load("__exc"))]
+
+        # Apply visitor to each statement
+        for stmt in stmts:
+            self.visitor(stmt)
+
+        return stmts
+
+    def translate(self, expression, target):
+        if isinstance(target, string_type):
+            target = store(target)
+
+        cached = self.cache.get(expression)
+
+        if cached is not None:
+            stmts = [ast.Assign(targets=[target], value=cached)]
+        elif isinstance(expression, ast.expr):
+            stmts = [ast.Assign(targets=[target], value=expression)]
+        else:
+            # The engine interface supports simple strings, which
+            # default to expression nodes
+            if isinstance(expression, string_type):
+                expression = Value(expression, True)
+
+            kind = type(expression).__name__
+            visitor = getattr(self, "visit_%s" % kind)
+            stmts = visitor(expression, target)
+
+            # Add comment
+            target_id = getattr(target, "id", target)
+            comment = Comment(" %r -> %s" % (expression, target_id))
+            stmts.insert(0, comment)
+
+        return stmts
+
+    def visit_Value(self, node, target):
+        engine = self.engine_factory()
+        compiler = engine.parse(node.value)
+        return compiler.assign_value(target)
+
+    def visit_Default(self, node, target):
+        value = annotated(node.marker)
+        return [ast.Assign(targets=[target], value=value)]
+
+    def visit_Substitution(self, node, target):
+        engine = self.engine_factory(
+            char_escape=node.char_escape,
+            default=node.default,
+            )
+        compiler = engine.parse(node.value)
+        return compiler.assign_text(target)
+
+    def visit_Negate(self, node, target):
+        return self.translate(node.value, target) + \
+               template("TARGET = not TARGET", TARGET=target)
+
+    def visit_Identity(self, node, target):
+        expression = self.translate(node.expression, "__expression")
+        value = self.translate(node.value, "__value")
+
+        return expression + value + \
+               template("TARGET = __expression is __value", TARGET=target)
+
+    def visit_Equality(self, node, target):
+        expression = self.translate(node.expression, "__expression")
+        value = self.translate(node.value, "__value")
+
+        return expression + value + \
+               template("TARGET = __expression == __value", TARGET=target)
+
+    def visit_Boolean(self, node, target):
+        engine = self.engine_factory()
+        compiler = engine.parse(node.value)
+        return compiler.assign_bool(target, node.s)
+
+    def visit_Interpolation(self, node, target):
+        expr = node.value
+        if isinstance(expr, Substitution):
+            engine = self.engine_factory(
+                char_escape=expr.char_escape,
+                default=expr.default,
+                )
+        elif isinstance(expr, Value):
+            engine = self.engine_factory()
+        else:
+            raise RuntimeError("Bad value: %r." % node.value)
+
+        interpolator = Interpolator(
+            expr.value, node.braces_required, node.translation
+            )
+
+        compiler = engine.get_compiler(interpolator, expr.value)
+        return compiler(target, engine)
+
+    def visit_Translate(self, node, target):
+        if node.msgid is not None:
+            msgid = ast.Str(s=node.msgid)
+        else:
+            msgid = target
+        return self.translate(node.node, target) + \
+               emit_translate(target, msgid, default=target)
+
+    def visit_Static(self, node, target):
+        value = annotated(node)
+        return [ast.Assign(targets=[target], value=value)]
+
+    def visit_Builtin(self, node, target):
+        value = annotated(node)
+        return [ast.Assign(targets=[target], value=value)]
+
+
+class Compiler(object):
+    """Generic compiler class.
+
+    Iterates through nodes and yields Python statements which form a
+    template program.
+    """
+
+    exceptions = NameError, \
+                 ValueError, \
+                 AttributeError, \
+                 LookupError, \
+                 TypeError
+
+    defaults = {
+        'translate': Symbol(fast_translate),
+        'decode': Builtin("str"),
+        'convert': Builtin("str"),
+        }
+
+    lock = threading.Lock()
+
+    global_builtins = set(builtins.__dict__)
+
+    def __init__(self, engine_factory, node, builtins={}, strict=True):
+        self._scopes = [set()]
+        self._expression_cache = {}
+        self._translations = []
+        self._builtins = builtins
+        self._aliases = [{}]
+        self._macros = []
+        self._current_slot = []
+
+        internals = COMPILER_INTERNALS_OR_DISALLOWED | \
+                    set(self.defaults)
+
+        transform = NameTransform(
+            self.global_builtins | set(builtins),
+            ListDictProxy(self._aliases),
+            internals,
+            )
+
+        self._visitor = visitor = NameLookupRewriteVisitor(transform)
+
+        self._engine = ExpressionTransform(
+            engine_factory,
+            self._expression_cache,
+            visitor,
+            strict=strict,
+            )
+
+        if isinstance(node_annotations, dict):
+            self.lock.acquire()
+            backup = node_annotations.copy()
+        else:
+            backup = None
+
+        try:
+            module = ast.Module([])
+            module.body += self.visit(node)
+            ast.fix_missing_locations(module)
+            generator = TemplateCodeGenerator(module)
+        finally:
+            if backup is not None:
+                node_annotations.clear()
+                node_annotations.update(backup)
+                self.lock.release()
+
+        self.code = generator.code
+
+    def visit(self, node):
+        if node is None:
+            return ()
+        kind = type(node).__name__
+        visitor = getattr(self, "visit_%s" % kind)
+        iterator = visitor(node)
+        return list(iterator)
+
+    def visit_Sequence(self, node):
+        for item in node.items:
+            for stmt in self.visit(item):
+                yield stmt
+
+    def visit_Element(self, node):
+        self._aliases.append(self._aliases[-1].copy())
+
+        for stmt in self.visit(node.start):
+            yield stmt
+
+        for stmt in self.visit(node.content):
+            yield stmt
+
+        if node.end is not None:
+            for stmt in self.visit(node.end):
+                yield stmt
+
+        self._aliases.pop()
+
+    def visit_Module(self, node):
+        body = []
+
+        body += template("import re")
+        body += template("import functools")
+        body += template("__marker = object()")
+        body += template(
+            r"g_re_amp = re.compile(r'&(?!([A-Za-z]+|#[0-9]+);)')"
+        )
+        body += template(
+            r"g_re_needs_escape = re.compile(r'[&<>\"\']').search")
+
+        body += template(
+            r"__re_whitespace = "
+            r"functools.partial(re.compile('\s+').sub, ' ')",
+        )
+
+        # Visit module content
+        program = self.visit(node.program)
+
+        body += [ast.FunctionDef(
+            name=node.name, args=ast.arguments(
+                args=[param(b) for b in self._builtins],
+                defaults=(),
+                ),
+            body=program
+            )]
+
+        return body
+
+    def visit_MacroProgram(self, node):
+        functions = []
+
+        # Visit defined macros
+        macros = getattr(node, "macros", ())
+        names = []
+        for macro in macros:
+            stmts = self.visit(macro)
+            function = stmts[-1]
+            names.append(function.name)
+            functions += stmts
+
+        # Return function dictionary
+        functions += [ast.Return(value=ast.Dict(
+            keys=[ast.Str(s=name) for name in names],
+            values=[load(name) for name in names],
+            ))]
+
+        return functions
+
+    def visit_Context(self, node):
+        return template("getitem = econtext.__getitem__") + \
+               template("get = econtext.get") + \
+               self.visit(node.node)
+
+    def visit_Macro(self, node):
+        body = []
+
+        # Initialization
+        body += template("__append = __stream.append")
+        body += template("__re_amp = g_re_amp")
+        body += template("__re_needs_escape = g_re_needs_escape")
+
+        # Resolve defaults
+        for name in self.defaults:
+            body += template(
+                "NAME = econtext[KEY]",
+                NAME=name, KEY=ast.Str(s="__" + name)
+            )
+
+        # Internal set of defined slots
+        self._slots = set()
+
+        # Visit macro body
+        nodes = itertools.chain(*tuple(map(self.visit, node.body)))
+
+        # Slot resolution
+        for name in self._slots:
+            body += template(
+                "try: NAME = econtext[KEY].pop()\n"
+                "except: NAME = None",
+                KEY=ast.Str(s=name), NAME=store(name))
+
+        # Append visited nodes
+        body += nodes
+
+        function_name = "render" if node.name is None else \
+                        "render_%s" % mangle(node.name)
+
+        function = ast.FunctionDef(
+            name=function_name, args=ast.arguments(
+                args=[
+                    param("__stream"),
+                    param("econtext"),
+                    param("rcontext"),
+                    param("__i18n_domain"),
+                    ],
+                defaults=[load("None")],
+            ),
+            body=body
+            )
+
+        yield function
+
+    def visit_Text(self, node):
+        return emit_node(ast.Str(s=node.value))
+
+    def visit_Domain(self, node):
+        backup = "__previous_i18n_domain_%d" % id(node)
+        return template("BACKUP = __i18n_domain", BACKUP=backup) + \
+               template("__i18n_domain = NAME", NAME=ast.Str(s=node.name)) + \
+               self.visit(node.node) + \
+               template("__i18n_domain = BACKUP", BACKUP=backup)
+
+    def visit_OnError(self, node):
+        body = []
+
+        fallback = identifier("__fallback")
+        body += template("fallback = len(__stream)", fallback=fallback)
+
+        self._enter_assignment((node.name, ))
+        fallback_body = self.visit(node.fallback)
+        self._leave_assignment((node.name, ))
+
+        error_assignment = template(
+            "econtext[key] = cls(__exc, rcontext['__error__'][-1][1:3])",
+            cls=ErrorInfo,
+            key=ast.Str(s=node.name),
+            )
+
+        body += [ast.TryExcept(
+            body=self.visit(node.node),
+            handlers=[ast.ExceptHandler(
+                type=ast.Tuple(elts=[Builtin("Exception")], ctx=ast.Load()),
+                name=store("__exc"),
+                body=(error_assignment + \
+                      template("del __stream[fallback:]", fallback=fallback) + \
+                      fallback_body
+                      ),
+                )]
+            )]
+
+        return body
+
+    def visit_Content(self, node):
+        name = "__content"
+        body = self._engine(node.expression, store(name))
+
+        if node.translate:
+            body += emit_translate(name, name)
+
+        if node.char_escape:
+            body += emit_convert_and_escape(name)
+        else:
+            body += emit_convert(name)
+
+        body += template("if NAME is not None: __append(NAME)", NAME=name)
+
+        return body
+
+    def visit_Interpolation(self, node):
+        name = identifier("content")
+        return self._engine(node, name) + \
+               emit_node_if_non_trivial(name)
+
+    def visit_Alias(self, node):
+        assert len(node.names) == 1
+        name = node.names[0]
+        target = self._aliases[-1][name] = identifier(name, id(node))
+        return self._engine(node.expression, target)
+
+    def visit_Assignment(self, node):
+        for name in node.names:
+            if name in COMPILER_INTERNALS_OR_DISALLOWED:
+                raise TranslationError(
+                    "Name disallowed by compiler.", name
+                    )
+
+            if name.startswith('__'):
+                raise TranslationError(
+                    "Name disallowed by compiler (double underscore).",
+                    name
+                    )
+
+        assignment = self._engine(node.expression, store("__value"))
+
+        if len(node.names) != 1:
+            target = ast.Tuple(
+                elts=[store_econtext(name) for name in node.names],
+                ctx=ast.Store(),
+            )
+        else:
+            target = store_econtext(node.names[0])
+
+        assignment.append(ast.Assign(targets=[target], value=load("__value")))
+
+        for name in node.names:
+            if not node.local:
+                assignment += template(
+                    "rcontext[KEY] = __value", KEY=ast.Str(s=native_string(name))
+                    )
+
+        return assignment
+
+    def visit_Define(self, node):
+        scope = set(self._scopes[-1])
+        self._scopes.append(scope)
+
+        for assignment in node.assignments:
+            if assignment.local:
+                for stmt in self._enter_assignment(assignment.names):
+                    yield stmt
+
+            for stmt in self.visit(assignment):
+                yield stmt
+
+        for stmt in self.visit(node.node):
+            yield stmt
+
+        for assignment in node.assignments:
+            if assignment.local:
+                for stmt in self._leave_assignment(assignment.names):
+                    yield stmt
+
+        self._scopes.pop()
+
+    def visit_Omit(self, node):
+        return self.visit_Condition(node)
+
+    def visit_Condition(self, node):
+        target = "__condition"
+        assignment = self._engine(node.expression, target)
+
+        assert assignment
+
+        for stmt in assignment:
+            yield stmt
+
+        body = self.visit(node.node) or [ast.Pass()]
+
+        orelse = getattr(node, "orelse", None)
+        if orelse is not None:
+            orelse = self.visit(orelse)
+
+        test = load(target)
+
+        yield ast.If(test=test, body=body, orelse=orelse)
+
+    def visit_Translate(self, node):
+        """Translation.
+
+        Visit items and assign output to a default value.
+
+        Finally, compile a translation expression and use either
+        result or default.
+        """
+
+        body = []
+
+        # Track the blocks of this translation
+        self._translations.append(set())
+
+        # Prepare new stream
+        append = identifier("append", id(node))
+        stream = identifier("stream", id(node))
+        body += template("s = new_list", s=stream, new_list=LIST) + \
+                template("a = s.append", a=append, s=stream)
+
+        # Visit body to generate the message body
+        code = self.visit(node.node)
+        swap(ast.Suite(body=code), load(append), "__append")
+        body += code
+
+        # Reduce white space and assign as message id
+        msgid = identifier("msgid", id(node))
+        body += template(
+            "msgid = __re_whitespace(''.join(stream)).strip()",
+            msgid=msgid, stream=stream
+        )
+
+        default = msgid
+
+        # Compute translation block mapping if applicable
+        names = self._translations[-1]
+        if names:
+            keys = []
+            values = []
+
+            for name in names:
+                stream, append = self._get_translation_identifiers(name)
+                keys.append(ast.Str(s=name))
+                values.append(load(stream))
+
+                # Initialize value
+                body.insert(
+                    0, ast.Assign(
+                        targets=[store(stream)],
+                        value=ast.Str(s=native_string(""))))
+
+            mapping = ast.Dict(keys=keys, values=values)
+        else:
+            mapping = None
+
+        # if this translation node has a name, use it as the message id
+        if node.msgid:
+            msgid = ast.Str(s=node.msgid)
+
+        # emit the translation expression
+        body += template(
+            "__append(translate("
+            "msgid, mapping=mapping, default=default, domain=__i18n_domain, context=econtext))",
+            msgid=msgid, default=default, mapping=mapping
+            )
+
+        # pop away translation block reference
+        self._translations.pop()
+
+        return body
+
+    def visit_Start(self, node):
+        try:
+            line, column = node.prefix.location
+        except AttributeError:
+            line, column = 0, 0
+
+        yield Comment(
+            " %s%s ... (%d:%d)\n"
+            " --------------------------------------------------------" % (
+                node.prefix, node.name, line, column))
+
+        if node.attributes:
+            for stmt in emit_node(ast.Str(s=node.prefix + node.name)):
+                yield stmt
+
+            for attribute in node.attributes:
+                for stmt in self.visit(attribute):
+                    yield stmt
+
+            for stmt in emit_node(ast.Str(s=node.suffix)):
+                yield stmt
+        else:
+            for stmt in emit_node(
+                ast.Str(s=node.prefix + node.name + node.suffix)):
+                yield stmt
+
+    def visit_End(self, node):
+        for stmt in emit_node(ast.Str(
+            s=node.prefix + node.name + node.space + node.suffix)):
+            yield stmt
+
+    def visit_Attribute(self, node):
+        f = node.space + node.name + node.eq + node.quote + "%s" + node.quote
+
+        # Static attributes are just outputted directly
+        if isinstance(node.expression, ast.Str):
+            s = f % node.expression.s
+            return template("__append(S)", S=ast.Str(s=s))
+
+        target = identifier("attr", node.name)
+        body = self._engine(node.expression, store(target))
+        return body + template(
+            "if TARGET is not None: __append(FORMAT % TARGET)",
+            FORMAT=ast.Str(s=f),
+            TARGET=target,
+            )
+
+    def visit_Cache(self, node):
+        body = []
+
+        for expression in node.expressions:
+            name = identifier("cache", id(expression))
+            target = store(name)
+
+            # Skip re-evaluation
+            if self._expression_cache.get(expression):
+                continue
+
+            body += self._engine(expression, target)
+            self._expression_cache[expression] = target
+
+        body += self.visit(node.node)
+
+        return body
+
+    def visit_UseInternalMacro(self, node):
+        if node.name is None:
+            render = "render"
+        else:
+            render = "render_%s" % mangle(node.name)
+
+        return template(
+            "f(__stream, econtext.copy(), rcontext, __i18n_domain)",
+            f=render) + \
+            template("econtext.update(rcontext)")
+
+    def visit_DefineSlot(self, node):
+        name = "__slot_%s" % mangle(node.name)
+        body = self.visit(node.node)
+
+        self._slots.add(name)
+
+        orelse = template(
+            "SLOT(__stream, econtext.copy(), rcontext)",
+            SLOT=name)
+        test = ast.Compare(
+            left=load(name),
+            ops=[ast.Is()],
+            comparators=[load("None")]
+            )
+
+        return [
+            ast.If(test=test, body=body or [ast.Pass()], orelse=orelse)
+            ]
+
+    def visit_Name(self, node):
+        """Translation name."""
+
+        if not self._translations:
+            raise TranslationError(
+                "Not allowed outside of translation.", node.name)
+
+        if node.name in self._translations[-1]:
+            raise TranslationError(
+                "Duplicate translation name: %s." % node.name)
+
+        self._translations[-1].add(node.name)
+        body = []
+
+        # prepare new stream
+        stream, append = self._get_translation_identifiers(node.name)
+        body += template("s = new_list", s=stream, new_list=LIST) + \
+                template("a = s.append", a=append, s=stream)
+
+        # generate code
+        code = self.visit(node.node)
+        swap(ast.Suite(body=code), load(append), "__append")
+        body += code
+
+        # output msgid
+        text = Text('${%s}' % node.name)
+        body += self.visit(text)
+
+        # Concatenate stream
+        body += template("stream = ''.join(stream)", stream=stream)
+
+        return body
+
+    def visit_CodeBlock(self, node):
+        stmts = template(textwrap.dedent(node.source.strip('\n')))
+
+        for stmt in stmts:
+            self._visitor(stmt)
+
+        return stmts
+
+    def visit_UseExternalMacro(self, node):
+        self._macros.append(node.extend)
+
+        callbacks = []
+        for slot in node.slots:
+            key = "__slot_%s" % mangle(slot.name)
+            fun = "__fill_%s" % mangle(slot.name)
+
+            self._current_slot.append(slot.name)
+
+            body = template("getitem = econtext.__getitem__") + \
+                   template("get = econtext.get") + \
+                   self.visit(slot.node)
+
+            assert self._current_slot.pop() == slot.name
+
+            callbacks.append(
+                ast.FunctionDef(
+                    name=fun,
+                    args=ast.arguments(
+                        args=[
+                            param("__stream"),
+                            param("econtext"),
+                            param("rcontext"),
+                            param("__i18n_domain"),
+                            ],
+                        defaults=[load("__i18n_domain")],
+                        ),
+                    body=body or [ast.Pass()],
+                ))
+
+            key = ast.Str(s=key)
+
+            assignment = template(
+                "_slots = econtext[KEY] = DEQUE((NAME,))",
+                KEY=key, NAME=fun, DEQUE=Symbol(collections.deque),
+                )
+
+            if node.extend:
+                append = template("_slots.appendleft(NAME)", NAME=fun)
+
+                assignment = [ast.TryExcept(
+                    body=template("_slots = getitem(KEY)", KEY=key),
+                    handlers=[ast.ExceptHandler(body=assignment)],
+                    orelse=append,
+                    )]
+
+            callbacks.extend(assignment)
+
+        assert self._macros.pop() == node.extend
+
+        assignment = self._engine(node.expression, store("__macro"))
+
+        return (
+            callbacks + \
+            assignment + \
+            template(
+                "__macro.include(__stream, econtext.copy(), " \
+                "rcontext, __i18n_domain)") + \
+            template("econtext.update(rcontext)")
+            )
+
+    def visit_Repeat(self, node):
+        # Used for loop variable definition and restore
+        self._scopes.append(set())
+
+        # Variable assignment and repeat key for single- and
+        # multi-variable repeat clause
+        if node.local:
+            contexts = "econtext",
+        else:
+            contexts = "econtext", "rcontext"
+
+        for name in node.names:
+            if name in COMPILER_INTERNALS_OR_DISALLOWED:
+                raise TranslationError(
+                    "Name disallowed by compiler.", name
+                    )
+
+        if len(node.names) > 1:
+            targets = [
+                ast.Tuple(elts=[
+                    subscript(native_string(name), load(context), ast.Store())
+                    for name in node.names], ctx=ast.Store())
+                for context in contexts
+                ]
+
+            key = ast.Tuple(
+                elts=[ast.Str(s=name) for name in node.names],
+                ctx=ast.Load())
+        else:
+            name = node.names[0]
+            targets = [
+                subscript(native_string(name), load(context), ast.Store())
+                for context in contexts
+                ]
+
+            key = ast.Str(s=node.names[0])
+
+        index = identifier("__index", id(node))
+        assignment = [ast.Assign(targets=targets, value=load("__item"))]
+
+        # Make repeat assignment in outer loop
+        names = node.names
+        local = node.local
+
+        outer = self._engine(node.expression, store("__iterator"))
+
+        if local:
+            outer[:] = list(self._enter_assignment(names)) + outer
+
+        outer += template(
+            "__iterator, INDEX = getitem('repeat')(key, __iterator)",
+            key=key, INDEX=index
+            )
+
+        # Set a trivial default value for each name assigned to make
+        # sure we assign a value even if the iteration is empty
+        outer += [ast.Assign(
+            targets=[store_econtext(name)
+                     for name in node.names],
+            value=load("None"))
+              ]
+
+        # Compute inner body
+        inner = self.visit(node.node)
+
+        # After each iteration, decrease the index
+        inner += template("index -= 1", index=index)
+
+        # For items up to N - 1, emit repeat whitespace
+        inner += template(
+            "if INDEX > 0: __append(WHITESPACE)",
+            INDEX=index, WHITESPACE=ast.Str(s=node.whitespace)
+            )
+
+        # Main repeat loop
+        outer += [ast.For(
+            target=store("__item"),
+            iter=load("__iterator"),
+            body=assignment + inner,
+            )]
+
+        # Finally, clean up assignment if it's local
+        if outer:
+            outer += self._leave_assignment(names)
+
+        self._scopes.pop()
+
+        return outer
+
+    def _get_translation_identifiers(self, name):
+        assert self._translations
+        prefix = id(self._translations[-1])
+        stream = identifier("stream_%d" % prefix, name)
+        append = identifier("append_%d" % prefix, name)
+        return stream, append
+
+    def _enter_assignment(self, names):
+        for name in names:
+            for stmt in template(
+                "BACKUP = get(KEY, __marker)",
+                BACKUP=identifier("backup_%s" % name, id(names)),
+                KEY=ast.Str(s=native_string(name)),
+                ):
+                yield stmt
+
+    def _leave_assignment(self, names):
+        for name in names:
+            for stmt in template(
+                "if BACKUP is __marker: del econtext[KEY]\n"
+                "else:                 econtext[KEY] = BACKUP",
+                BACKUP=identifier("backup_%s" % name, id(names)),
+                KEY=ast.Str(s=native_string(name)),
+                ):
+                yield stmt
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/config.py b/lib3/Chameleon-2.9.2/src/chameleon/config.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/config.py
@@ -0,0 +1,47 @@
+import os
+import logging
+
+log = logging.getLogger('chameleon.config')
+
+# Define which values are read as true
+TRUE = ('y', 'yes', 't', 'true', 'on', '1')
+
+# If eager parsing is enabled, templates are parsed upon
+# instantiation, rather than when first called upon; this mode is
+# useful for verifying validity of templates across a project
+EAGER_PARSING = os.environ.pop('CHAMELEON_EAGER', 'false')
+EAGER_PARSING = EAGER_PARSING.lower() in TRUE
+
+# Debug mode is mostly useful for debugging the template engine
+# itself. When enabled, generated source code is written to disk to
+# ease step-debugging and some log levels are lowered to increase
+# output. Also, the generated source code is available in the
+# ``source`` attribute of the template instance if compilation
+# succeeded.
+DEBUG_MODE = os.environ.pop('CHAMELEON_DEBUG', 'false')
+DEBUG_MODE = DEBUG_MODE.lower() in TRUE
+
+# If a cache directory is specified, template source code will be
+# persisted on disk and reloaded between sessions
+path = os.environ.pop('CHAMELEON_CACHE', None)
+if path is not None:
+    CACHE_DIRECTORY = os.path.abspath(path)
+    if not os.path.exists(CACHE_DIRECTORY):
+        raise ValueError(
+            "Cache directory does not exist: %s." % CACHE_DIRECTORY
+            )
+    log.info("directory cache: %s." % CACHE_DIRECTORY)
+else:
+    CACHE_DIRECTORY = None
+
+# When auto-reload is enabled, templates are reloaded on file change.
+AUTO_RELOAD = os.environ.pop('CHAMELEON_RELOAD', 'false')
+AUTO_RELOAD = AUTO_RELOAD.lower() in TRUE
+
+for key in os.environ:
+    if key.lower().startswith('chameleon'):
+        log.warn("unknown environment variable set: \"%s\"." % key)
+
+# This is the slice length of the expression displayed in the
+# formatted exception string
+SOURCE_EXPRESSION_MARKER_LENGTH = 60
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/exc.py b/lib3/Chameleon-2.9.2/src/chameleon/exc.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/exc.py
@@ -0,0 +1,289 @@
+# -*- coding: utf-8 -*-
+
+import traceback
+
+from .utils import format_kwargs
+from .utils import safe_native
+from .tokenize import Token
+from .config import SOURCE_EXPRESSION_MARKER_LENGTH as LENGTH
+
+
+def compute_source_marker(line, column, expression, size):
+    """Computes source marker location string.
+
+    >>> def test(l, c, e, s):
+    ...     s, marker = compute_source_marker(l, c, e, s)
+    ...     out = s + '\\n' + marker
+    ...
+    ...     # Replace dot with middle-dot to work around doctest ellipsis
+    ...     print(out.replace('...', '···'))
+
+    >>> test('foo bar', 4, 'bar', 7)
+    foo bar
+        ^^^
+
+    >>> test('foo ${bar}', 4, 'bar', 10)
+    foo ${bar}
+          ^^^
+
+    >>> test('  foo bar', 6, 'bar', 6)
+    ··· oo bar
+           ^^^
+
+    >>> test('  foo bar baz  ', 6, 'bar', 6)
+    ··· o bar ···
+          ^^^
+
+    The entire expression is always shown, even if ``size`` does not
+    accomodate for it.
+
+    >>> test('  foo bar baz  ', 6, 'bar baz', 10)
+    ··· oo bar baz
+           ^^^^^^^
+
+    >>> test('      foo bar', 10, 'bar', 5)
+    ··· o bar
+          ^^^
+
+    >>> test('      foo bar', 10, 'boo', 5)
+    ··· o bar
+          ^
+
+    """
+
+    s = line.lstrip()
+    column -= len(line) - len(s)
+    s = s.rstrip()
+
+    try:
+        i  = s[column:].index(expression)
+    except ValueError:
+        # If we can't find the expression
+        # (this shouldn't happen), simply
+        # use a standard size marker
+        marker = "^"
+    else:
+        column += i
+        marker = "^" * len(expression)
+
+    if len(expression) > size:
+        offset = column
+        size = len(expression)
+    else:
+        window = (size - len(expression)) / 2.0
+        offset = column - window
+        offset -= min(3, max(0, column + window + len(expression) - len(s)))
+        offset = int(offset)
+
+    if offset > 0:
+        s = s[offset:]
+        r = s.lstrip()
+        d = len(s) - len(r)
+        s = "... " + r
+        column += 4 - d
+        column -= offset
+
+        # This also adds to the displayed length
+        size += 4
+
+    if len(s) > size:
+        s = s[:size].rstrip() + " ..."
+
+    return s, column * " " + marker
+
+
+def ellipsify(string, limit):
+    if len(string) > limit:
+        return "... " + string[-(limit - 4):]
+
+
+def reconstruct_exc(cls, state):
+    exc = Exception.__new__(cls)
+    exc.__dict__ = state
+    return exc
+
+
+class TemplateError(Exception):
+    """An error raised by Chameleon.
+
+    >>> from chameleon.tokenize import Token
+    >>> token = Token('token')
+    >>> message = 'message'
+
+    Make sure the exceptions can be copied:
+
+    >>> from copy import copy
+    >>> copy(TemplateError(message, token))
+    TemplateError('message', 'token')
+
+    And pickle/unpickled:
+
+    >>> from pickle import dumps, loads
+    >>> loads(dumps(TemplateError(message, token)))
+    TemplateError('message', 'token')
+
+    """
+
+    def __init__(self, msg, token):
+        if not isinstance(token, Token):
+            token = Token(token, 0)
+
+        self.msg = msg
+        self.token = safe_native(token)
+        self.offset = getattr(token, "pos", 0)
+        self.filename = token.filename
+
+    def __copy__(self):
+        inst = Exception.__new__(type(self))
+        inst.__dict__ = self.__dict__.copy()
+        return inst
+
+    def __reduce__(self):
+        return reconstruct_exc, (type(self), self.__dict__)
+
+    def __str__(self):
+        text = "%s\n\n" % self.msg
+        text += " - String:     \"%s\"" % self.token
+
+        if self.filename:
+            text += "\n"
+            text += " - Filename:   %s" % self.filename
+
+        try:
+            line, column = self.token.location
+        except AttributeError:
+            pass
+        else:
+            text += "\n"
+            text += " - Location:   (%d:%d)" % (line, column)
+
+        return text
+
+    def __repr__(self):
+        try:
+            return "%s('%s', '%s')" % (
+                self.__class__.__name__, self.msg, self.token
+                )
+        except AttributeError:
+            return object.__repr__(self)
+
+
+class ParseError(TemplateError):
+    """An error occurred during parsing.
+
+    Indicates an error on the structural level.
+    """
+
+
+class CompilationError(TemplateError):
+    """An error occurred during compilation.
+
+    Indicates a general compilation error.
+    """
+
+
+class TranslationError(TemplateError):
+    """An error occurred during translation.
+
+    Indicates a general translation error.
+    """
+
+
+class LanguageError(CompilationError):
+    """Language syntax error.
+
+    Indicates a syntactical error due to incorrect usage of the
+    template language.
+    """
+
+
+class ExpressionError(LanguageError):
+    """An error occurred compiling an expression.
+
+    Indicates a syntactical error in an expression.
+    """
+
+
+class ExceptionFormatter(object):
+    def __init__(self, errors, econtext, rcontext):
+        kwargs = rcontext.copy()
+        kwargs.update(econtext)
+
+        for name in tuple(kwargs):
+            if name.startswith('__'):
+                del kwargs[name]
+
+        self._errors = errors
+        self._kwargs = kwargs
+
+    def __call__(self):
+        # Format keyword arguments; consecutive arguments are indented
+        # for readability
+        try:
+            formatted = format_kwargs(self._kwargs)
+        except:
+            # the ``pprint.pformat`` method calls the representation
+            # method of the arguments; this may fail and since we're
+            # already in an exception handler, there's no point in
+            # pursuing this further
+            formatted = ()
+
+        for index, string in enumerate(formatted[1:]):
+            formatted[index + 1] = " " * 15 + string
+
+        out = []
+        seen = set()
+
+        for error in reversed(self._errors):
+            expression, line, column, filename, exc = error
+
+            if exc in seen:
+                continue
+
+            seen.add(exc)
+
+            if isinstance(exc, UnicodeDecodeError):
+                string = safe_native(exc.object)
+
+                s, marker = compute_source_marker(
+                    string, exc.start, string[exc.start:exc.end], LENGTH
+                    )
+
+                out.append(" - Stream:     %s" % s)
+                out.append("               %s" % marker)
+
+            _filename = ellipsify(filename, 60) if filename else "<string>"
+
+            out.append(" - Expression: \"%s\"" % expression)
+            out.append(" - Filename:   %s" % _filename)
+            out.append(" - Location:   (%d:%d)" % (line, column))
+
+            if filename and line and column:
+                try:
+                    f = open(filename, 'r')
+                except IOError:
+                    pass
+                else:
+                    try:
+                        # Pick out source line and format marker
+                        for i, l in enumerate(f):
+                            if i + 1 == line:
+                                s, marker = compute_source_marker(
+                                    l, column, expression, LENGTH
+                                    )
+
+                                out.append(" - Source:     %s" % s)
+                                out.append("               %s" % marker)
+                                break
+                    finally:
+                        f.close()
+
+        out.append(" - Arguments:  %s" % "\n".join(formatted))
+
+        formatted = traceback.format_exception_only(type(exc), exc)[-1]
+        formatted_class = "%s:" % type(exc).__name__
+
+        if formatted.startswith(formatted_class):
+            formatted = formatted[len(formatted_class):].lstrip()
+
+        return "\n".join(map(safe_native, [formatted] + out))
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/i18n.py b/lib3/Chameleon-2.9.2/src/chameleon/i18n.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/i18n.py
@@ -0,0 +1,120 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import re
+
+from .exc import CompilationError
+from .utils import unicode_string
+
+NAME_RE = r"[a-zA-Z][-a-zA-Z0-9_]*"
+
+WHITELIST = frozenset([
+    "translate",
+    "domain",
+    "target",
+    "source",
+    "attributes",
+    "data",
+    "name",
+    "mode",
+    "xmlns",
+    "xml"
+    ])
+
+_interp_regex = re.compile(r'(?<!\$)(\$(?:(%(n)s)|{(%(n)s)}))'
+    % ({'n': NAME_RE}))
+
+
+try:  # pragma: no cover
+    str = unicode
+except NameError:
+    pass
+
+try:  # pragma: no cover
+    # optional: `zope.i18n`, `zope.i18nmessageid`
+    from zope.i18n import interpolate
+    from zope.i18n import translate
+    from zope.i18nmessageid import Message
+except ImportError:   # pragma: no cover
+
+    def fast_translate(msgid, domain=None, mapping=None, context=None,
+                       target_language=None, default=None):
+        if default is None:
+            return msgid
+
+        if mapping:
+            def replace(match):
+                whole, param1, param2 = match.groups()
+                return unicode_string(mapping.get(param1 or param2, whole))
+            return _interp_regex.sub(replace, default)
+
+        return default
+else:   # pragma: no cover
+    def fast_translate(msgid, domain=None, mapping=None, context=None,
+                       target_language=None, default=None):
+        if msgid is None:
+            return
+
+        if target_language is not None or context is not None:
+            result = translate(
+                msgid, domain=domain, mapping=mapping, context=context,
+                target_language=target_language, default=default)
+            if result != msgid:
+                return result
+
+        if isinstance(msgid, Message):
+            default = msgid.default
+            mapping = msgid.mapping
+
+        if default is None:
+            default = str(msgid)
+
+        if not isinstance(default, basestring):
+            return default
+
+        return interpolate(default, mapping)
+
+
+def parse_attributes(attrs, xml=True):
+    d = {}
+
+    # filter out empty items, eg:
+    # i18n:attributes="value msgid; name msgid2;"
+    # would result in 3 items where the last one is empty
+    attrs = [spec for spec in attrs.split(";") if spec]
+
+    for spec in attrs:
+        if ',' in spec:
+            raise CompilationError(
+                "Attribute must not contain comma. Use semicolon to "
+                "list multiple attributes", spec
+                )
+        parts = spec.split()
+        if len(parts) == 2:
+            attr, msgid = parts
+        elif len(parts) == 1:
+            attr = parts[0]
+            msgid = None
+        else:
+            raise CompilationError(
+                "Illegal i18n:attributes specification.", spec)
+        if not xml:
+            attr = attr.lower()
+        attr = attr.strip()
+        if attr in d:
+            raise CompilationError(
+                "Attribute may only be specified once in i18n:attributes", attr)
+        d[attr] = msgid
+
+    return d
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/interfaces.py b/lib3/Chameleon-2.9.2/src/chameleon/interfaces.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/interfaces.py
@@ -0,0 +1,102 @@
+from zope.interface import Interface
+from zope.interface import Attribute
+
+
+class ITALExpressionErrorInfo(Interface):
+
+    type = Attribute("type",
+                     "The exception class.")
+
+    value = Attribute("value",
+                      "The exception instance.")
+
+    lineno = Attribute("lineno",
+                       "The line number the error occurred on in the source.")
+
+    offset = Attribute("offset",
+                       "The character offset at which the error occurred.")
+
+
+class ITALIterator(Interface):  # pragma: no cover
+    """A TAL iterator
+
+    Not to be confused with a Python iterator.
+    """
+
+    def next():
+        """Advance to the next value in the iteration, if possible
+
+        Return a true value if it was possible to advance and return
+        a false value otherwise.
+        """
+
+
+class ITALESIterator(ITALIterator):  # pragma: no cover
+    """TAL Iterator provided by TALES
+
+    Values of this iterator are assigned to items in the repeat namespace.
+
+    For example, with a TAL statement like: tal:repeat="item items",
+    an iterator will be assigned to "repeat/item".  The iterator
+    provides a number of handy methods useful in writing TAL loops.
+
+    The results are undefined of calling any of the methods except
+    'length' before the first iteration.
+    """
+
+    def index():
+        """Return the position (starting with "0") within the iteration
+        """
+
+    def number():
+        """Return the position (starting with "1") within the iteration
+        """
+
+    def even():
+        """Return whether the current position is even
+        """
+
+    def odd():
+        """Return whether the current position is odd
+        """
+
+    def parity():
+        """Return 'odd' or 'even' depending on the position's parity
+
+        Useful for assigning CSS class names to table rows.
+        """
+
+    def start():
+        """Return whether the current position is the first position
+        """
+
+    def end():
+        """Return whether the current position is the last position
+        """
+
+    def letter():
+        """Return the position (starting with "a") within the iteration
+        """
+
+    def Letter():
+        """Return the position (starting with "A") within the iteration
+        """
+
+    def roman():
+        """Return the position (starting with "i") within the iteration
+        """
+
+    def Roman():
+        """Return the position (starting with "I") within the iteration
+        """
+
+    def item():
+        """Return the item at the current position
+        """
+
+    def length():
+        """Return the length of the sequence
+
+        Note that this may fail if the TAL iterator was created on a Python
+        iterator.
+        """
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/loader.py b/lib3/Chameleon-2.9.2/src/chameleon/loader.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/loader.py
@@ -0,0 +1,174 @@
+import functools
+import imp
+import logging
+import os
+import py_compile
+import shutil
+import sys
+import tempfile
+import warnings
+
+import pkg_resources
+
+log = logging.getLogger('chameleon.loader')
+
+try:
+    str = unicode
+except NameError:
+    basestring = str
+
+
+def cache(func):
+    def load(self, *args, **kwargs):
+        template = self.registry.get(args)
+        if template is None:
+            self.registry[args] = template = func(self, *args, **kwargs)
+        return template
+    return load
+
+
+def abspath_from_asset_spec(spec):
+    pname, filename = spec.split(':', 1)
+    return pkg_resources.resource_filename(pname, filename)
+
+if os.name == "nt":
+    def abspath_from_asset_spec(spec, f=abspath_from_asset_spec):
+        if spec[1] == ":":
+            return spec
+        return f(spec)
+
+
+class TemplateLoader(object):
+    """Template loader class.
+
+    To load templates using relative filenames, pass a sequence of
+    paths (or a single path) as ``search_path``.
+
+    To apply a default filename extension to inputs which do not have
+    an extension already (i.e. no dot), provide this as
+    ``default_extension`` (e.g. ``'.pt'``).
+
+    Additional keyword-arguments will be passed on to the template
+    constructor.
+    """
+
+    default_extension = None
+
+    def __init__(self, search_path=None, default_extension=None, **kwargs):
+        if search_path is None:
+            search_path = []
+        if isinstance(search_path, basestring):
+            search_path = [search_path]
+        if default_extension is not None:
+            self.default_extension = ".%s" % default_extension.lstrip('.')
+        self.search_path = search_path
+        self.registry = {}
+        self.kwargs = kwargs
+
+    @cache
+    def load(self, spec, cls=None):
+        if cls is None:
+            raise ValueError("Unbound template loader.")
+
+        spec = spec.strip()
+
+        if self.default_extension is not None and '.' not in spec:
+            spec += self.default_extension
+
+        if ':' in spec:
+            spec = abspath_from_asset_spec(spec)
+
+        if os.path.isabs(spec):
+            return cls(spec, **self.kwargs)
+
+        for path in self.search_path:
+            path = os.path.join(path, spec)
+            if os.path.exists(path):
+                return cls(path, **self.kwargs)
+
+        raise ValueError("Template not found: %s." % spec)
+
+    def bind(self, cls):
+        return functools.partial(self.load, cls=cls)
+
+
+class MemoryLoader(object):
+    def build(self, source, filename):
+        code = compile(source, filename, 'exec')
+        env = {}
+        exec(code, env)
+        return env
+
+    def get(self, name):
+        return None
+
+
+class ModuleLoader(object):
+    def __init__(self, path, remove=False):
+        self.path = path
+        self.remove = remove
+
+    def __del__(self, shutil=shutil):
+        if not self.remove:
+            return
+        try:
+            shutil.rmtree(self.path)
+        except:
+            warnings.warn("Could not clean up temporary file path: %s" % (self.path,))
+
+    def get(self, filename):
+        path = os.path.join(self.path, filename)
+        if os.path.exists(path):
+            log.debug("loading module from cache: %s." % filename)
+            base, ext = os.path.splitext(filename)
+            return self._load(base, path)
+        else:
+            log.debug('cache miss: %s' % filename)
+
+    def build(self, source, filename):
+        imp.acquire_lock()
+        try:
+            d = self.get(filename)
+            if d is not None:
+                return d
+
+            base, ext = os.path.splitext(filename)
+            name = os.path.join(self.path, base + ".py")
+
+            log.debug("writing source to disk (%d bytes)." % len(source))
+            fd, fn = tempfile.mkstemp(prefix=base, suffix='.tmp', dir=self.path)
+            temp = os.fdopen(fd, 'w')
+
+            try:
+                try:
+                    temp.write("%s\n" % '# -*- coding: utf-8 -*-')
+                    temp.write(source)
+                finally:
+                    temp.close()
+            except:
+                os.remove(fn)
+                raise
+
+            os.rename(fn, name)
+            log.debug("compiling %s into byte-code..." % filename)
+            py_compile.compile(name)
+
+            return self._load(base, name)
+        finally:
+            imp.release_lock()
+
+    def _load(self, base, filename):
+        imp.acquire_lock()
+        try:
+            module = sys.modules.get(base)
+            if module is None:
+                f = open(filename, 'rb')
+                try:
+                    assert base not in sys.modules
+                    module = imp.load_source(base, filename, f)
+                finally:
+                    f.close()
+        finally:
+            imp.release_lock()
+
+        return module.__dict__
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/metal.py b/lib3/Chameleon-2.9.2/src/chameleon/metal.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/metal.py
@@ -0,0 +1,23 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+WHITELIST = frozenset([
+    "define-macro",
+    "extend-macro",
+    "use-macro",
+    "define-slot",
+    "fill-slot",
+    "xmlns",
+    "xml"
+    ])
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/namespaces.py b/lib3/Chameleon-2.9.2/src/chameleon/namespaces.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/namespaces.py
@@ -0,0 +1,9 @@
+XML_NS = "http://www.w3.org/XML/1998/namespace"
+XMLNS_NS = "http://www.w3.org/2000/xmlns/"
+XHTML_NS = "http://www.w3.org/1999/xhtml"
+TAL_NS = "http://xml.zope.org/namespaces/tal"
+META_NS = "http://xml.zope.org/namespaces/meta"
+METAL_NS = "http://xml.zope.org/namespaces/metal"
+XI_NS = "http://www.w3.org/2001/XInclude"
+I18N_NS = "http://xml.zope.org/namespaces/i18n"
+PY_NS = "http://genshi.edgewall.org/"
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/nodes.py b/lib3/Chameleon-2.9.2/src/chameleon/nodes.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/nodes.py
@@ -0,0 +1,210 @@
+from .astutil import Node
+
+
+class UseExternalMacro(Node):
+    """Extend external macro."""
+
+    _fields = "expression", "slots", "extend"
+
+
+class Sequence(Node):
+    """Element sequence."""
+
+    _fields = "items",
+
+
+class Content(Node):
+    """Content substitution."""
+
+    _fields = "expression", "char_escape", "translate"
+
+
+class Default(Node):
+    """Represents a default value."""
+
+    _fields = "marker",
+
+
+class CodeBlock(Node):
+    _fields = "source",
+
+
+class Value(Node):
+    """Expression object value."""
+
+    _fields = "value",
+
+    def __repr__(self):
+        try:
+            line, column = self.value.location
+        except AttributeError:
+            line, column = 0, 0
+
+        return "<%s %r (%d:%d)>" % (
+            type(self).__name__, self.value, line, column
+            )
+
+
+class Substitution(Value):
+    """Expression value for text substitution."""
+
+    _fields = "value", "char_escape", "default"
+
+    default = None
+
+
+class Boolean(Value):
+    _fields = "value", "s"
+
+
+class Negate(Node):
+    """Wraps an expression with a negation."""
+
+    _fields = "value",
+
+
+class Element(Node):
+    """XML element."""
+
+    _fields = "start", "end", "content"
+
+
+class Attribute(Node):
+    """Element attribute."""
+
+    _fields = "name", "expression", "quote", "eq", "space"
+
+
+class Start(Node):
+    """Start-tag."""
+
+    _fields = "name", "prefix", "suffix", "attributes"
+
+
+class End(Node):
+    """End-tag."""
+
+    _fields = "name", "space", "prefix", "suffix"
+
+
+class Condition(Node):
+    """Node visited only if some condition holds."""
+
+    _fields = "expression", "node", "orelse"
+
+
+class Identity(Node):
+    """Condition expression that is true on identity."""
+
+    _fields = "expression", "value"
+
+
+class Equality(Node):
+    """Condition expression that is true on equality."""
+
+    _fields = "expression", "value"
+
+
+class Cache(Node):
+    """Cache (evaluate only once) the value of ``expression`` inside
+    ``node``.
+    """
+
+    _fields = "expressions", "node"
+
+
+class Assignment(Node):
+    """Variable assignment."""
+
+    _fields = "names", "expression", "local"
+
+
+class Alias(Assignment):
+    """Alias assignment.
+
+    Note that ``expression`` should be a cached or global value.
+    """
+
+    local = False
+
+
+class Define(Node):
+    """Variable definition in scope."""
+
+    _fields = "assignments", "node"
+
+
+class Repeat(Assignment):
+    """Iterate over provided assignment and repeat body."""
+
+    _fields = "names", "expression", "local", "whitespace", "node"
+
+
+class Macro(Node):
+    """Macro definition."""
+
+    _fields = "name", "body"
+
+
+class Program(Node):
+    _fields = "name", "body"
+
+
+class Module(Node):
+    _fields = "name", "program",
+
+
+class Context(Node):
+    _fields = "node",
+
+
+class Text(Node):
+    """Static text output."""
+
+    _fields = "value",
+
+
+class Interpolation(Text):
+    """String interpolation output."""
+
+    _fields = "value", "braces_required", "translation"
+
+
+class Translate(Node):
+    """Translate node."""
+
+    _fields = "msgid", "node"
+
+
+class Name(Node):
+    """Translation name."""
+
+    _fields = "name", "node"
+
+
+class Domain(Node):
+    """Update translation domain."""
+
+    _fields = "name", "node"
+
+
+class OnError(Node):
+    _fields = "fallback", "name", "node"
+
+
+class UseInternalMacro(Node):
+    """Use internal macro (defined inside same program)."""
+
+    _fields = "name",
+
+
+class FillSlot(Node):
+    """Fill a macro slot."""
+
+    _fields = "name", "node"
+
+
+class DefineSlot(Node):
+    """Define a macro slot."""
+
+    _fields = "name", "node"
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/parser.py b/lib3/Chameleon-2.9.2/src/chameleon/parser.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/parser.py
@@ -0,0 +1,238 @@
+import re
+import logging
+
+try:
+    from collections import OrderedDict
+except ImportError:
+    from ordereddict import OrderedDict
+
+from .exc import ParseError
+from .namespaces import XML_NS
+from .tokenize import Token
+
+match_tag_prefix_and_name = re.compile(
+    r'^(?P<prefix></?)(?P<name>([^:\n ]+:)?[^ \n\t>/]+)'
+    '(?P<suffix>(?P<space>\s*)/?>)?',
+    re.UNICODE | re.DOTALL)
+match_single_attribute = re.compile(
+    r'(?P<space>\s+)(?!\d)'
+    r'(?P<name>[^ =/>\n\t]+)'
+    r'((?P<eq>\s*=\s*)'
+    r'((?P<quote>[\'"])(?P<value>.*?)(?P=quote)|'
+    r'(?P<alt_value>[^\s\'">/]+))|'
+    r'(?P<simple_value>(?![ \\n\\t\\r]*=)))',
+    re.UNICODE | re.DOTALL)
+match_comment = re.compile(
+    r'^<!--(?P<text>.*)-->$', re.DOTALL)
+match_cdata = re.compile(
+    r'^<!\[CDATA\[(?P<text>.*)\]>$', re.DOTALL)
+match_declaration = re.compile(
+    r'^<!(?P<text>[^>]+)>$', re.DOTALL)
+match_processing_instruction = re.compile(
+    r'^<\?(?P<name>\w+)(?P<text>.*?)\?>', re.DOTALL)
+match_xml_declaration = re.compile(r'^<\?xml(?=[ /])', re.DOTALL)
+
+log = logging.getLogger('chameleon.parser')
+
+
+def substitute(regex, repl, token):
+    if not isinstance(token, Token):
+        token = Token(token)
+
+    return Token(
+        regex.sub(repl, token),
+        token.pos,
+        token.source,
+        token.filename
+        )
+
+
+def groups(m, token):
+    result = []
+    for i, group in enumerate(m.groups()):
+        if group is not None:
+            j, k = m.span(i + 1)
+            group = token[j:k]
+
+        result.append(group)
+
+    return tuple(result)
+
+
+def groupdict(m, token):
+    d = m.groupdict()
+    for name, value in d.items():
+        if value is not None:
+            i, j = m.span(name)
+            d[name] = token[i:j]
+
+    return d
+
+
+def match_tag(token, regex=match_tag_prefix_and_name):
+    m = regex.match(token)
+    d = groupdict(m, token)
+
+    end = m.end()
+    token = token[end:]
+
+    attrs = d['attrs'] = []
+    for m in match_single_attribute.finditer(token):
+        attr = groupdict(m, token)
+        alt_value = attr.pop('alt_value', None)
+        if alt_value is not None:
+            attr['value'] = alt_value
+            attr['quote'] = ''
+        simple_value = attr.pop('simple_value', None)
+        if simple_value is not None:
+            attr['quote'] = ''
+            attr['value'] = ''
+            attr['eq'] = ''
+        attrs.append(attr)
+        d['suffix'] = token[m.end():]
+
+    return d
+
+
+def parse_tag(token, namespace):
+    node = match_tag(token)
+
+    update_namespace(node['attrs'], namespace)
+
+    if ':' in node['name']:
+        prefix = node['name'].split(':')[0]
+    else:
+        prefix = None
+
+    default = node['namespace'] = namespace.get(prefix, XML_NS)
+
+    node['ns_attrs'] = unpack_attributes(
+        node['attrs'], namespace, default)
+
+    return node
+
+
+def update_namespace(attributes, namespace):
+    # possibly update namespaces; we do this in a separate step
+    # because this assignment is irrespective of order
+    for attribute in attributes:
+        name = attribute['name']
+        value = attribute['value']
+        if name == 'xmlns':
+            namespace[None] = value
+        elif name.startswith('xmlns:'):
+            namespace[name[6:]] = value
+
+
+def unpack_attributes(attributes, namespace, default):
+    namespaced = OrderedDict()
+
+    for index, attribute in enumerate(attributes):
+        name = attribute['name']
+        value = attribute['value']
+
+        if ':' in name:
+            prefix = name.split(':')[0]
+            name = name[len(prefix) + 1:]
+            try:
+                ns = namespace[prefix]
+            except KeyError:
+                raise KeyError(
+                    "Undefined namespace prefix: %s." % prefix)
+        else:
+            ns = default
+        namespaced[ns, name] = value
+
+    return namespaced
+
+
+def identify(string):
+    if string.startswith("<"):
+        if string.startswith("<!--"):
+            return "comment"
+        if string.startswith("<![CDATA["):
+            return "cdata"
+        if string.startswith("<!"):
+            return "declaration"
+        if string.startswith("<?xml"):
+            return "xml_declaration"
+        if string.startswith("<?"):
+            return "processing_instruction"
+        if string.startswith("</"):
+            return "end_tag"
+        if string.endswith("/>"):
+            return "empty_tag"
+        if string.endswith(">"):
+            return "start_tag"
+        return "error"
+    return "text"
+
+
+class ElementParser(object):
+    """Parses tokens into elements."""
+
+    def __init__(self, stream, default_namespaces):
+        self.stream = stream
+        self.queue = []
+        self.index = []
+        self.namespaces = [default_namespaces.copy()]
+
+    def __iter__(self):
+        for token in self.stream:
+            item = self.parse(token)
+            self.queue.append(item)
+
+        return iter(self.queue)
+
+    def parse(self, token):
+        kind = identify(token)
+        visitor = getattr(self, "visit_%s" % kind, self.visit_default)
+        return visitor(kind, token)
+
+    def visit_comment(self, kind, token):
+        return "comment", (token, )
+
+    def visit_cdata(self, kind, token):
+        return "cdata", (token, )
+
+    def visit_default(self, kind, token):
+        return "default", (token, )
+
+    def visit_processing_instruction(self, kind, token):
+        m = match_processing_instruction.match(token)
+        return "processing_instruction", (groupdict(m, token), )
+
+    def visit_text(self, kind, token):
+        return kind, (token, )
+
+    def visit_start_tag(self, kind, token):
+        namespace = self.namespaces[-1].copy()
+        self.namespaces.append(namespace)
+        node = parse_tag(token, namespace)
+        self.index.append((node['name'], len(self.queue)))
+        return kind, (node, )
+
+    def visit_end_tag(self, kind, token):
+        try:
+            namespace = self.namespaces.pop()
+        except IndexError:
+            raise ParseError("Unexpected end tag.", token)
+
+        node = parse_tag(token, namespace)
+
+        while self.index:
+            name, pos = self.index.pop()
+            if name == node['name']:
+                start, = self.queue.pop(pos)[1]
+                children = self.queue[pos:]
+                del self.queue[pos:]
+                break
+        else:
+            raise ParseError("Unexpected end tag.", token)
+
+        return "element", (start, node, children)
+
+    def visit_empty_tag(self, kind, token):
+        namespace = self.namespaces[-1].copy()
+        node = parse_tag(token, namespace)
+        return "element", (node, None, [])
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/program.py b/lib3/Chameleon-2.9.2/src/chameleon/program.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/program.py
@@ -0,0 +1,38 @@
+try:
+    str = unicode
+except NameError:
+    long = int
+
+from .tokenize import iter_xml
+from .tokenize import iter_text
+from .parser import ElementParser
+from .namespaces import XML_NS
+from .namespaces import XMLNS_NS
+
+
+class ElementProgram(object):
+    DEFAULT_NAMESPACES = {
+        'xmlns': XMLNS_NS,
+        'xml': XML_NS,
+        }
+
+    tokenizers = {
+        'xml': iter_xml,
+        'text': iter_text,
+        }
+
+    def __init__(self, source, mode="xml", filename=None):
+        tokenizer = self.tokenizers[mode]
+        tokens = tokenizer(source, filename)
+        parser = ElementParser(tokens, self.DEFAULT_NAMESPACES)
+
+        self.body = []
+
+        for kind, args in parser:
+            node = self.visit(kind, args)
+            if node is not None:
+                self.body.append(node)
+
+    def visit(self, kind, args):
+        visitor = getattr(self, "visit_%s" % kind)
+        return visitor(*args)
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/py25.py b/lib3/Chameleon-2.9.2/src/chameleon/py25.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/py25.py
@@ -0,0 +1,36 @@
+import sys
+
+def lookup_attr(obj, key):
+    try:
+        return getattr(obj, key)
+    except AttributeError:
+        exc = sys.exc_info()[1]
+        try:
+            get = obj.__getitem__
+        except AttributeError:
+            raise exc
+        try:
+            return get(key)
+        except KeyError:
+            raise exc
+
+def exec_(code, globs=None, locs=None):
+    """Execute code in a namespace."""
+    if globs is None:
+        frame = sys._getframe(1)
+        globs = frame.f_globals
+        if locs is None:
+            locs = frame.f_locals
+        del frame
+    elif locs is None:
+        locs = globs
+    exec("""exec code in globs, locs""")
+
+
+exec_("""def raise_with_traceback(exc, tb):
+    raise type(exc), exc, tb
+""")
+
+
+def next(iter):
+    return iter.next()
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/py26.py b/lib3/Chameleon-2.9.2/src/chameleon/py26.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/py26.py
@@ -0,0 +1,15 @@
+import sys
+
+def lookup_attr(obj, key):
+    try:
+        return getattr(obj, key)
+    except AttributeError:
+        exc = sys.exc_info()[1]
+        try:
+            get = obj.__getitem__
+        except AttributeError:
+            raise exc
+        try:
+            return get(key)
+        except KeyError:
+            raise exc
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tal.py b/lib3/Chameleon-2.9.2/src/chameleon/tal.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tal.py
@@ -0,0 +1,479 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+import re
+import copy
+
+from .exc import LanguageError
+from .utils import descriptorint
+from .utils import descriptorstr
+from .namespaces import XMLNS_NS
+from .parser import groups
+
+
+try:
+    next
+except NameError:
+    from chameleon.py25 import next
+
+try:
+    # optional library: `zope.interface`
+    import interfaces
+    import zope.interface
+except ImportError:
+    interfaces = None
+
+
+NAME = r"[a-zA-Z_][-a-zA-Z0-9_]*"
+DEFINE_RE = re.compile(r"(?s)\s*(?:(global|local)\s+)?" +
+                       r"(%s|\(%s(?:,\s*%s)*\))\s+(.*)\Z" % (NAME, NAME, NAME),
+                       re.UNICODE)
+SUBST_RE = re.compile(r"\s*(?:(text|structure)\s+)?(.*)\Z", re.S | re.UNICODE)
+ATTR_RE = re.compile(r"\s*([^\s]+)\s+([^\s].*)\Z", re.S | re.UNICODE)
+
+ENTITY_RE = re.compile(r'(&(#?)(x?)(\d{1,5}|\w{1,8});)')
+
+WHITELIST = frozenset([
+    "define",
+    "comment",
+    "condition",
+    "content",
+    "replace",
+    "repeat",
+    "attributes",
+    "on-error",
+    "omit-tag",
+    "script",
+    "switch",
+    "case",
+    "xmlns",
+    "xml"
+    ])
+
+
+def split_parts(arg):
+    # Break in pieces at undoubled semicolons and
+    # change double semicolons to singles:
+    i = 0
+    while i < len(arg):
+        m = ENTITY_RE.search(arg[i:])
+        if m is None:
+            break
+        arg = arg[:i + m.end()] + ';' + arg[i + m.end():]
+        i += m.end()
+
+    arg = arg.replace(";;", "\0")
+    parts = arg.split(';')
+    parts = [p.replace("\0", ";") for p in parts]
+    if len(parts) > 1 and not parts[-1].strip():
+        del parts[-1]  # It ended in a semicolon
+
+    return parts
+
+
+def parse_attributes(clause):
+    attrs = {}
+    for part in split_parts(clause):
+        m = ATTR_RE.match(part)
+        if not m:
+            raise LanguageError(
+                "Bad syntax in attributes.", clause)
+        name, expr = groups(m, part)
+        if name in attrs:
+            raise LanguageError(
+                "Duplicate attribute name in attributes.", part)
+
+        attrs[name] = expr
+
+    return attrs
+
+
+def parse_substitution(clause):
+    m = SUBST_RE.match(clause)
+    if m is None:
+        raise LanguageError(
+            "Invalid content substitution syntax.", clause)
+
+    key, expression = groups(m, clause)
+    if not key:
+        key = "text"
+
+    return key, expression
+
+
+def parse_defines(clause):
+    """
+    Parses a tal:define value.
+
+    # Basic syntax, implicit local
+    >>> parse_defines('hello lovely')
+    [('local', ('hello',), 'lovely')]
+
+    # Explicit local
+    >>> parse_defines('local hello lovely')
+    [('local', ('hello',), 'lovely')]
+
+    # With global
+    >>> parse_defines('global hello lovely')
+    [('global', ('hello',), 'lovely')]
+
+    # Multiple expressions
+    >>> parse_defines('hello lovely; tea time')
+    [('local', ('hello',), 'lovely'), ('local', ('tea',), 'time')]
+
+    # With multiple names
+    >>> parse_defines('(hello, howdy) lovely')
+    [('local', ['hello', 'howdy'], 'lovely')]
+
+    # With unicode whitespace
+    >>> try:
+    ...     s = '\xc2\xa0hello lovely'.decode('utf-8')
+    ... except AttributeError:
+    ...     s = '\xa0hello lovely'
+    >>> from chameleon.utils import unicode_string
+    >>> parse_defines(s) == [
+    ...     ('local', ('hello',), 'lovely')
+    ... ]
+    True
+
+    """
+    defines = []
+    for part in split_parts(clause):
+        m = DEFINE_RE.match(part)
+        if m is None:
+            raise LanguageError("Invalid define syntax", part)
+        context, name, expr = groups(m, part)
+        context = context or "local"
+
+        if name.startswith('('):
+            names = [n.strip() for n in name.strip('()').split(',')]
+        else:
+            names = (name,)
+
+        defines.append((context, names, expr))
+
+    return defines
+
+
+def prepare_attributes(attrs, dyn_attributes, i18n_attributes,
+                       ns_attributes, drop_ns):
+    drop = set([attribute['name'] for attribute, (ns, value)
+                in zip(attrs, ns_attributes)
+                if ns in drop_ns or (
+                    ns == XMLNS_NS and
+                    attribute['value'] in drop_ns
+                    )
+                ])
+
+    attributes = []
+    normalized = {}
+
+    for attribute in attrs:
+        name = attribute['name']
+
+        if name in drop:
+            continue
+
+        attributes.append((
+            name,
+            attribute['value'],
+            attribute['quote'],
+            attribute['space'],
+            attribute['eq'],
+            None,
+            ))
+
+        normalized[name.lower()] = len(attributes) - 1
+
+    for name, expr in dyn_attributes.items():
+        index = normalized.get(name.lower())
+        if index is not None:
+            _, text, quote, space, eq, _ = attributes[index]
+            add = attributes.__setitem__
+        else:
+            text = None
+            quote = '"'
+            space = " "
+            eq = "="
+            index = len(attributes)
+            add = attributes.insert
+            normalized[name.lower()] = len(attributes) - 1
+
+        attribute = name, text, quote, space, eq, expr
+        add(index, attribute)
+
+    for name in i18n_attributes:
+        attr = name.lower()
+        if attr not in normalized:
+            attributes.append((name, name, '"', " ", "=", None))
+            normalized[attr] = len(attributes) - 1
+
+    return attributes
+
+
+class RepeatItem(object):
+    __slots__ = "length", "_iterator"
+
+    __allow_access_to_unprotected_subobjects__ = True
+
+    def __init__(self, iterator, length):
+        self.length = length
+        self._iterator = iterator
+
+    def __iter__(self):
+        return self._iterator
+
+    try:
+        iter(()).__len__
+    except AttributeError:
+        @descriptorint
+        def index(self):
+            try:
+                remaining = self._iterator.__length_hint__()
+            except AttributeError:
+                remaining = len(tuple(copy.copy(self._iterator)))
+            return self.length - remaining - 1
+    else:
+        @descriptorint
+        def index(self):
+            remaining = self._iterator.__len__()
+            return self.length - remaining - 1
+
+    @descriptorint
+    def start(self):
+        return self.index == 0
+
+    @descriptorint
+    def end(self):
+        return self.index == self.length - 1
+
+    @descriptorint
+    def number(self):
+        return self.index + 1
+
+    @descriptorstr
+    def odd(self):
+        """Returns a true value if the item index is odd.
+
+        >>> it = RepeatItem(iter(("apple", "pear")), 2)
+
+        >>> next(it._iterator)
+        'apple'
+        >>> it.odd()
+        ''
+
+        >>> next(it._iterator)
+        'pear'
+        >>> it.odd()
+        'odd'
+        """
+
+        return self.index % 2 == 1 and 'odd' or ''
+
+    @descriptorstr
+    def even(self):
+        """Returns a true value if the item index is even.
+
+        >>> it = RepeatItem(iter(("apple", "pear")), 2)
+
+        >>> next(it._iterator)
+        'apple'
+        >>> it.even()
+        'even'
+
+        >>> next(it._iterator)
+        'pear'
+        >>> it.even()
+        ''
+        """
+
+        return self.index % 2 == 0 and 'even' or ''
+
+    def next(self):
+        raise NotImplementedError(
+            "Method not implemented (can't update local variable).")
+
+    def _letter(self, base=ord('a'), radix=26):
+        """Get the iterator position as a lower-case letter
+
+        >>> it = RepeatItem(iter(("apple", "pear", "orange")), 3)
+        >>> next(it._iterator)
+        'apple'
+        >>> it.letter()
+        'a'
+        >>> next(it._iterator)
+        'pear'
+        >>> it.letter()
+        'b'
+        >>> next(it._iterator)
+        'orange'
+        >>> it.letter()
+        'c'
+        """
+
+        index = self.index
+        if index < 0:
+            raise TypeError("No iteration position")
+        s = ""
+        while 1:
+            index, off = divmod(index, radix)
+            s = chr(base + off) + s
+            if not index:
+                return s
+
+    letter = descriptorstr(_letter)
+
+    @descriptorstr
+    def Letter(self):
+        """Get the iterator position as an upper-case letter
+
+        >>> it = RepeatItem(iter(("apple", "pear", "orange")), 3)
+        >>> next(it._iterator)
+        'apple'
+        >>> it.Letter()
+        'A'
+        >>> next(it._iterator)
+        'pear'
+        >>> it.Letter()
+        'B'
+        >>> next(it._iterator)
+        'orange'
+        >>> it.Letter()
+        'C'
+        """
+
+        return self._letter(base=ord('A'))
+
+    @descriptorstr
+    def Roman(self, rnvalues=(
+                    (1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
+                    (100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
+                    (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I'))):
+        """Get the iterator position as an upper-case roman numeral
+
+        >>> it = RepeatItem(iter(("apple", "pear", "orange")), 3)
+        >>> next(it._iterator)
+        'apple'
+        >>> it.Roman()
+        'I'
+        >>> next(it._iterator)
+        'pear'
+        >>> it.Roman()
+        'II'
+        >>> next(it._iterator)
+        'orange'
+        >>> it.Roman()
+        'III'
+        """
+
+        n = self.index + 1
+        s = ""
+        for v, r in rnvalues:
+            rct, n = divmod(n, v)
+            s = s + r * rct
+        return s
+
+    @descriptorstr
+    def roman(self):
+        """Get the iterator position as a lower-case roman numeral
+
+        >>> it = RepeatItem(iter(("apple", "pear", "orange")), 3)
+        >>> next(it._iterator)
+        'apple'
+        >>> it.roman()
+        'i'
+        >>> next(it._iterator)
+        'pear'
+        >>> it.roman()
+        'ii'
+        >>> next(it._iterator)
+        'orange'
+        >>> it.roman()
+        'iii'
+        """
+
+        return self.Roman().lower()
+
+
+if interfaces is not None:
+    zope.interface.classImplements(RepeatItem, interfaces.ITALESIterator)
+
+
+class RepeatDict(dict):
+    """Repeat dictionary implementation.
+
+    >>> repeat = RepeatDict({})
+    >>> iterator, length = repeat('numbers', range(5))
+    >>> length
+    5
+
+    >>> repeat['numbers']
+    <chameleon.tal.RepeatItem object at ...>
+
+    """
+
+    __slots__ = "__setitem__", "__getitem__", "__getattr__"
+
+    def __init__(self, d):
+        self.__setitem__ = d.__setitem__
+        self.__getitem__ = d.__getitem__
+        self.__getattr__ = d.__getitem__
+
+    def __call__(self, key, iterable):
+        """We coerce the iterable to a tuple and return an iterator
+        after registering it in the repeat dictionary."""
+
+        try:
+            iterable = tuple(iterable)
+        except TypeError:
+            if iterable is None:
+                iterable = ()
+            else:
+                # The message below to the TypeError is the Python
+                # 2.5-style exception message. Python 2.4.X also
+                # raises a TypeError, but with a different message.
+                # ("TypeError: iteration over non-sequence").  The
+                # Python 2.5 error message is more helpful.  We
+                # construct the 2.5-style message explicitly here so
+                # that both Python 2.4.X and Python 2.5+ will raise
+                # the same error.  This makes writing the tests eaiser
+                # and makes the output easier to understand.
+                raise TypeError("%r object is not iterable" %
+                                type(iterable).__name__)
+
+        length = len(iterable)
+        iterator = iter(iterable)
+
+        # Insert as repeat item
+        self[key] = RepeatItem(iterator, length)
+
+        return iterator, length
+
+
+class ErrorInfo(object):
+    """Information about an exception passed to an on-error handler."""
+
+    def __init__(self, err, position=(None, None)):
+        if isinstance(err, Exception):
+            self.type = err.__class__
+            self.value = err
+        else:
+            self.type = err
+            self.value = None
+        self.lineno = position[0]
+        self.offset = position[1]
+
+
+if interfaces is not None:
+    zope.interface.classImplements(ErrorInfo, interfaces.ITALExpressionErrorInfo)
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tales.py b/lib3/Chameleon-2.9.2/src/chameleon/tales.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tales.py
@@ -0,0 +1,541 @@
+import re
+import sys
+
+from .astutil import parse
+from .astutil import store
+from .astutil import load
+from .astutil import ItemLookupOnAttributeErrorVisitor
+from .codegen import TemplateCodeGenerator
+from .codegen import template
+from .codegen import reverse_builtin_map
+from .astutil import Builtin
+from .astutil import Symbol
+from .exc import ExpressionError
+from .utils import resolve_dotted
+from .utils import Markup
+from .utils import ast
+from .tokenize import Token
+from .parser import substitute
+from .compiler import Interpolator
+
+try:
+    from .py26 import lookup_attr
+except SyntaxError:
+    from .py25 import lookup_attr
+
+
+split_parts = re.compile(r'(?<!\\)\|')
+match_prefix = re.compile(r'^\s*([a-z\-_]+):').match
+re_continuation = re.compile(r'\\\s*$', re.MULTILINE)
+
+try:
+    from __builtin__ import basestring
+except ImportError:
+    basestring = str
+
+
+def resolve_global(value):
+    name = reverse_builtin_map.get(value)
+    if name is not None:
+        return Builtin(name)
+
+    return Symbol(value)
+
+
+def test(expression, engine=None, **env):
+    if engine is None:
+        engine = SimpleEngine()
+
+    body = expression(store("result"), engine)
+    module = ast.Module(body)
+    module = ast.fix_missing_locations(module)
+    env['rcontext'] = {}
+    source = TemplateCodeGenerator(module).code
+    code = compile(source, '<string>', 'exec')
+    exec(code, env)
+    result = env["result"]
+
+    if isinstance(result, basestring):
+        result = str(result)
+
+    return result
+
+
+def transform_attribute(node):
+    return template(
+        "lookup(object, name)",
+        lookup=Symbol(lookup_attr),
+        object=node.value,
+        name=ast.Str(s=node.attr),
+        mode="eval"
+        )
+
+
+class TalesExpr(object):
+    """Base class.
+
+    This class helps implementations for the Template Attribute
+    Language Expression Syntax (TALES).
+
+    The syntax evaluates one or more expressions, separated by '|'
+    (pipe). The first expression that succeeds, is returned.
+
+    Expression:
+
+      expression    := (type ':')? line ('|' expression)?
+      line          := .*
+
+    Expression lines may not contain the pipe character unless
+    escaped. It has a special meaning:
+
+    If the expression to the left of the pipe fails (raises one of the
+    exceptions listed in ``catch_exceptions``), evaluation proceeds to
+    the expression(s) on the right.
+
+    Subclasses must implement ``translate`` which assigns a value for
+    a given expression.
+
+    >>> class PythonPipeExpr(TalesExpr):
+    ...     def translate(self, expression, target):
+    ...         compiler = PythonExpr(expression)
+    ...         return compiler(target, None)
+
+    >>> test(PythonPipeExpr('foo | bar | 42'))
+    42
+
+    >>> test(PythonPipeExpr('foo|42'))
+    42
+    """
+
+    exceptions = NameError, \
+                 ValueError, \
+                 AttributeError, \
+                 LookupError, \
+                 TypeError
+
+    def __init__(self, expression):
+        self.expression = expression
+
+    def __call__(self, target, engine):
+        remaining = self.expression
+        assignments = []
+
+        while remaining:
+            if match_prefix(remaining) is not None:
+                compiler = engine.parse(remaining)
+                assignment = compiler.assign_value(target)
+                remaining = ""
+            else:
+                for m in split_parts.finditer(remaining):
+                    expression = remaining[:m.start()]
+                    remaining = remaining[m.end():]
+                    break
+                else:
+                    expression = remaining
+                    remaining = ""
+
+                expression = expression.replace('\\|', '|')
+                assignment = self.translate(expression, target)
+            assignments.append(assignment)
+
+        if not assignments:
+            assignments.append(
+                self.translate(remaining, target)
+                )
+
+        for i, assignment in enumerate(reversed(assignments)):
+            if i == 0:
+                body = assignment
+            else:
+                body = [ast.TryExcept(
+                    body=assignment,
+                    handlers=[ast.ExceptHandler(
+                        type=ast.Tuple(
+                            elts=map(resolve_global, self.exceptions),
+                            ctx=ast.Load()),
+                        name=None,
+                        body=body,
+                        )],
+                    )]
+
+        return body
+
+    def translate(self, expression, target):
+        """Return statements that assign a value to ``target``."""
+
+        raise NotImplementedError(
+            "Must be implemented by a subclass.")
+
+
+class PathExpr(TalesExpr):
+    """Path expression compiler.
+
+    Syntax::
+
+        PathExpr ::= Path [ '|' Path ]*
+        Path ::= variable [ '/' URL_Segment ]*
+        variable ::= Name
+
+    For example::
+
+        request/cookies/oatmeal
+        nothing
+        here/some-file 2001_02.html.tar.gz/foo
+        root/to/branch | default
+
+    When a path expression is evaluated, it attempts to traverse
+    each path, from left to right, until it succeeds or runs out of
+    paths. To traverse a path, it first fetches the object stored in
+    the variable. For each path segment, it traverses from the current
+    object to the subobject named by the path segment.
+
+    Once a path has been successfully traversed, the resulting object
+    is the value of the expression. If it is a callable object, such
+    as a method or class, it is called.
+
+    The semantics of traversal (and what it means to be callable) are
+    implementation-dependent (see the ``translate`` method).
+    """
+
+    def translate(self, expression, target):
+        raise NotImplementedError(
+            "Path expressions are not yet implemented. "
+            "It's unclear whether a general implementation "
+            "can be devised.")
+
+
+class PythonExpr(TalesExpr):
+    """Python expression compiler.
+
+    >>> test(PythonExpr('2 + 2'))
+    4
+
+    The Python expression is a TALES expression. That means we can use
+    the pipe operator:
+
+    >>> test(PythonExpr('foo | 2 + 2 | 5'))
+    4
+
+    To include a pipe character, use a backslash escape sequence:
+
+    >>> test(PythonExpr('\"\|\"'))
+    '|'
+    """
+
+    transform = ItemLookupOnAttributeErrorVisitor(transform_attribute)
+
+    def parse(self, string):
+        return parse(string, 'eval').body
+
+    def translate(self, expression, target):
+        # Strip spaces
+        string = expression.strip()
+
+        # Conver line continuations to newlines
+        string = substitute(re_continuation, '\n', string)
+
+        # Convert newlines to spaces
+        string = string.replace('\n', ' ')
+
+        try:
+            value = self.parse(string)
+        except SyntaxError:
+            exc = sys.exc_info()[1]
+            raise ExpressionError(exc.msg, string)
+
+        # Transform attribute lookups to allow fallback to item lookup
+        self.transform.visit(value)
+
+        return [ast.Assign(targets=[target], value=value)]
+
+
+class ImportExpr(object):
+    re_dotted = re.compile(r'^[A-Za-z.]+$')
+
+    def __init__(self, expression):
+        self.expression = expression
+
+    def __call__(self, target, engine):
+        string = self.expression.strip().replace('\n', ' ')
+        value = template(
+            "RESOLVE(NAME)",
+            RESOLVE=Symbol(resolve_dotted),
+            NAME=ast.Str(s=string),
+            mode="eval",
+            )
+        return [ast.Assign(targets=[target], value=value)]
+
+
+class NotExpr(object):
+    """Negates the expression.
+
+    >>> engine = SimpleEngine(PythonExpr)
+
+    >>> test(NotExpr('False'), engine)
+    True
+    >>> test(NotExpr('True'), engine)
+    False
+    """
+
+    def __init__(self, expression):
+        self.expression = expression
+
+    def __call__(self, target, engine):
+        compiler = engine.parse(self.expression)
+        body = compiler.assign_value(target)
+        return body + template("target = not target", target=target)
+
+
+class StructureExpr(object):
+    """Wraps the expression result as 'structure'.
+
+    >>> engine = SimpleEngine(PythonExpr)
+
+    >>> test(StructureExpr('\"<tt>foo</tt>\"'), engine)
+    '<tt>foo</tt>'
+    """
+
+    wrapper_class = Symbol(Markup)
+
+    def __init__(self, expression):
+        self.expression = expression
+
+    def __call__(self, target, engine):
+        compiler = engine.parse(self.expression)
+        body = compiler.assign_value(target)
+        return body + template(
+            "target = wrapper(target)",
+            target=target,
+            wrapper=self.wrapper_class
+            )
+
+
+class IdentityExpr(object):
+    """Identity expression.
+
+    Exists to demonstrate the interface.
+
+    >>> test(IdentityExpr('42'))
+    42
+    """
+
+    def __init__(self, expression):
+        self.expression = expression
+
+    def __call__(self, target, engine):
+        compiler = engine.parse(self.expression)
+        return compiler.assign_value(target)
+
+
+class StringExpr(object):
+    """Similar to the built-in ``string.Template``, but uses an
+    expression engine to support pluggable string substitution
+    expressions.
+
+    Expr string:
+
+      string       := (text | substitution) (string)?
+      substitution := ('$' variable | '${' expression '}')
+      text         := .*
+
+    In other words, an expression string can contain multiple
+    substitutions. The text- and substitution parts will be
+    concatenated back into a string.
+
+    >>> test(StringExpr('Hello ${name}!'), name='world')
+    'Hello world!'
+
+    In the default configuration, braces may be omitted if the
+    expression is an identifier.
+
+    >>> test(StringExpr('Hello $name!'), name='world')
+    'Hello world!'
+
+    The ``braces_required`` flag changes this setting:
+
+    >>> test(StringExpr('Hello $name!', True))
+    'Hello $name!'
+
+    We can escape interpolation using the standard escaping
+    syntax:
+
+    >>> test(StringExpr('\\${name}'))
+    '\\\${name}'
+
+    Multiple interpolations in one:
+
+    >>> test(StringExpr(\"Hello ${'a'}${'b'}${'c'}!\"))
+    'Hello abc!'
+
+    Here's a more involved example taken from a javascript source:
+
+    >>> result = test(StringExpr(\"\"\"
+    ... function(oid) {
+    ...     $('#' + oid).autocomplete({source: ${'source'}});
+    ... }
+    ... \"\"\"))
+
+    >>> 'source: source' in result
+    True
+
+    In the above examples, the expression is evaluated using the
+    dummy engine which just returns the input as a string.
+
+    As an example, we'll implement an expression engine which
+    instead counts the number of characters in the expresion and
+    returns an integer result.
+
+    >>> class engine:
+    ...     @staticmethod
+    ...     def parse(expression):
+    ...         class compiler:
+    ...             @staticmethod
+    ...             def assign_text(target):
+    ...                 return [
+    ...                     ast.Assign(
+    ...                         targets=[target],
+    ...                         value=ast.Num(n=len(expression))
+    ...                     )]
+    ...
+    ...         return compiler
+
+    This will demonstrate how the string expression coerces the
+    input to a string.
+
+    >>> expr = StringExpr(
+    ...    'There are ${hello world} characters in \"hello world\"')
+
+    We evaluate the expression using the new engine:
+
+    >>> test(expr, engine)
+    'There are 11 characters in \"hello world\"'
+    """
+
+    def __init__(self, expression, braces_required=False):
+        # The code relies on the expression being a token string
+        if not isinstance(expression, Token):
+            expression = Token(expression, 0)
+
+        self.translator = Interpolator(expression, braces_required)
+
+    def __call__(self, name, engine):
+        return self.translator(name, engine)
+
+
+class ProxyExpr(StringExpr):
+    def __init__(self, name, *args):
+        super(ProxyExpr, self).__init__(*args)
+        self.name = name
+
+    def __call__(self, target, engine):
+        assignment = super(ProxyExpr, self).__call__(target, engine)
+        return assignment + [
+            ast.Assign(targets=[target], value=ast.Call(
+                func=load(self.name),
+                args=[target],
+                keywords=[],
+                starargs=None,
+                kwargs=None
+                ))
+            ]
+
+
+class ExistsExpr(object):
+    """Boolean wrapper.
+
+    Return 0 if the expression results in an exception, otherwise 1.
+
+    As a means to generate exceptions, we set up an expression engine
+    which evaluates the provided expression using Python:
+
+    >>> engine = SimpleEngine(PythonExpr)
+
+    >>> test(ExistsExpr('int(0)'), engine)
+    1
+    >>> test(ExistsExpr('int(None)'), engine)
+    0
+
+    """
+
+    exceptions = AttributeError, LookupError, TypeError, NameError, KeyError
+
+    def __init__(self, expression):
+        self.expression = expression
+
+    def __call__(self, target, engine):
+        ignore = store("_ignore")
+        compiler = engine.parse(self.expression)
+        body = compiler.assign_value(ignore)
+
+        classes = map(resolve_global, self.exceptions)
+
+        return [
+            ast.TryExcept(
+                body=body,
+                handlers=[ast.ExceptHandler(
+                    type=ast.Tuple(elts=classes, ctx=ast.Load()),
+                    name=None,
+                    body=template("target = 0", target=target),
+                    )],
+                orelse=template("target = 1", target=target)
+                )
+            ]
+
+
+class ExpressionParser(object):
+    def __init__(self, factories, default):
+        self.factories = factories
+        self.default = default
+
+    def __call__(self, expression):
+        m = match_prefix(expression)
+        if m is not None:
+            prefix = m.group(1)
+            expression = expression[m.end():]
+        else:
+            prefix = self.default
+
+        try:
+            factory = self.factories[prefix]
+        except KeyError:
+            exc = sys.exc_info()[1]
+            raise LookupError(
+                "Unknown expression type: %s." % str(exc)
+                )
+
+        return factory(expression)
+
+
+class SimpleEngine(object):
+    expression = PythonExpr
+
+    def __init__(self, expression=None):
+        if expression is not None:
+            self.expression = expression
+
+    def parse(self, string):
+        compiler = self.expression(string)
+        return SimpleCompiler(compiler, self)
+
+
+class SimpleCompiler(object):
+    def __init__(self, compiler, engine):
+        self.compiler = compiler
+        self.engine = engine
+
+    def assign_text(self, target):
+        """Assign expression string as a text value."""
+
+        return self._assign_value_and_coerce(target, "str")
+
+    def assign_value(self, target):
+        """Assign expression string as object value."""
+
+        return self.compiler(target, self.engine)
+
+    def _assign_value_and_coerce(self, target, builtin):
+        return self.assign_value(target) + template(
+            "target = builtin(target)",
+            target=target,
+            builtin=builtin
+            )
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/template.py b/lib3/Chameleon-2.9.2/src/chameleon/template.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/template.py
@@ -0,0 +1,332 @@
+from __future__ import with_statement
+
+import os
+import sys
+import copy
+import hashlib
+import shutil
+import logging
+import tempfile
+import inspect
+
+pkg_digest = hashlib.sha1(__name__.encode('utf-8'))
+
+try:
+    import pkg_resources
+except ImportError:
+    logging.info("Setuptools not installed. Unable to determine version.")
+else:
+    for path in sys.path:
+        for distribution in pkg_resources.find_distributions(path):
+            if distribution.has_version():
+                version = distribution.version.encode('utf-8')
+                pkg_digest.update(version)
+
+
+from .exc import TemplateError
+from .exc import ExceptionFormatter
+from .compiler import Compiler
+from .config import DEBUG_MODE
+from .config import AUTO_RELOAD
+from .config import EAGER_PARSING
+from .config import CACHE_DIRECTORY
+from .loader import ModuleLoader
+from .loader import MemoryLoader
+from .nodes import Module
+from .utils import DebuggingOutputStream
+from .utils import Scope
+from .utils import join
+from .utils import mangle
+from .utils import create_formatted_exception
+from .utils import read_bytes
+from .utils import raise_with_traceback
+from .utils import byte_string
+
+
+log = logging.getLogger('chameleon.template')
+
+
+def _make_module_loader():
+    remove = False
+    if CACHE_DIRECTORY:
+        path = CACHE_DIRECTORY
+    else:
+        path = tempfile.mkdtemp()
+        remove = True
+
+    return ModuleLoader(path)
+
+
+class BaseTemplate(object):
+    """Template base class.
+
+    Takes a string input which must be one of the following:
+
+    - a unicode string (or string on Python 3);
+    - a utf-8 encoded byte string;
+    - a byte string for an XML document that defines an encoding
+      in the document premamble;
+    - an HTML document that specifies the encoding via the META tag.
+
+    Note that the template input is decoded, parsed and compiled on
+    initialization.
+    """
+
+    default_encoding = "utf-8"
+
+    # This attribute is strictly informational in this template class
+    # and is used in exception formatting. It may be set on
+    # initialization using the optional ``filename`` keyword argument.
+    filename = '<string>'
+
+    _cooked = False
+
+    if DEBUG_MODE or CACHE_DIRECTORY:
+        loader = _make_module_loader()
+    else:
+        loader = MemoryLoader()
+
+    if DEBUG_MODE:
+        output_stream_factory = DebuggingOutputStream
+    else:
+        output_stream_factory = list
+
+    debug = DEBUG_MODE
+
+    # The ``builtins`` dictionary can be used by a template class to
+    # add symbols which may not be redefined and which are (cheaply)
+    # available in the template variable scope
+    builtins = {}
+
+    # The ``builtins`` dictionary is updated with this dictionary at
+    # cook time. Note that it can be provided at class initialization
+    # using the ``extra_builtins`` keyword argument.
+    extra_builtins = {}
+
+    # Expression engine must be provided by subclass
+    engine = None
+
+    # When ``strict`` is set, expressions must be valid at compile
+    # time. When not set, this is only required at evaluation time.
+    strict = True
+
+    def __init__(self, body=None, **config):
+        self.__dict__.update(config)
+
+        if body is not None:
+            self.write(body)
+
+        # This is only necessary if the ``debug`` flag was passed as a
+        # keyword argument
+        if self.__dict__.get('debug') is True:
+            self.loader = _make_module_loader()
+
+    def __call__(self, **kwargs):
+        return self.render(**kwargs)
+
+    def __repr__(self):
+        return "<%s %s>" % (self.__class__.__name__, self.filename)
+
+    @property
+    def keep_body(self):
+        # By default, we only save the template body if we're
+        # in debugging mode (to save memory).
+        return self.__dict__.get('keep_body', DEBUG_MODE)
+
+    @property
+    def keep_source(self):
+        # By default, we only save the generated source code if we're
+        # in debugging mode (to save memory).
+        return self.__dict__.get('keep_source', DEBUG_MODE)
+
+    def cook(self, body):
+        digest = self._digest(body)
+        builtins_dict = self.builtins.copy()
+        builtins_dict.update(self.extra_builtins)
+        names, builtins = zip(*builtins_dict.items())
+        program = self._cook(body, digest, names)
+
+        initialize = program['initialize']
+        functions = initialize(*builtins)
+
+        for name, function in functions.items():
+            setattr(self, "_" + name, function)
+
+        self._cooked = True
+
+        if self.keep_body:
+            self.body = body
+
+    def cook_check(self):
+        assert self._cooked
+
+    def parse(self, body):
+        raise NotImplementedError("Must be implemented by subclass.")
+
+    def render(self, **__kw):
+        econtext = Scope(__kw)
+        rcontext = {}
+        self.cook_check()
+        stream = self.output_stream_factory()
+        try:
+            self._render(stream, econtext, rcontext)
+        except:
+            cls, exc, tb = sys.exc_info()
+            errors = rcontext.get('__error__')
+            if errors:
+                formatter = exc.__str__
+                if isinstance(formatter, ExceptionFormatter):
+                    if errors is not formatter._errors:
+                        formatter._errors.extend(errors)
+                    raise
+
+                formatter = ExceptionFormatter(errors, econtext, rcontext)
+
+                try:
+                    exc = create_formatted_exception(exc, cls, formatter)
+                except TypeError:
+                    pass
+
+                raise_with_traceback(exc, tb)
+
+            raise
+
+        return join(stream)
+
+    def write(self, body):
+        if isinstance(body, byte_string):
+            body, encoding, content_type = read_bytes(
+                body, self.default_encoding
+                )
+        else:
+            content_type = body.startswith('<?xml')
+            encoding = None
+
+        self.content_type = content_type
+        self.content_encoding = encoding
+
+        self.cook(body)
+
+    def _get_module_name(self, digest):
+        return "%s.py" % digest
+
+    def _cook(self, body, digest, builtins):
+        name = self._get_module_name(digest)
+        cooked = self.loader.get(name)
+        if cooked is None:
+            try:
+                source = self._make(body, builtins)
+                if self.debug:
+                    source = "# template: %s\n#\n%s" % (self.filename, source)
+                if self.keep_source:
+                    self.source = source
+                cooked = self.loader.build(source, name)
+            except TemplateError:
+                exc = sys.exc_info()[1]
+                exc.filename = self.filename
+                raise
+        elif self.keep_source:
+            module = sys.modules.get(cooked.get('__name__'))
+            if module is not None:
+                self.source = inspect.getsource(module)
+            else:
+                self.source = None
+
+        return cooked
+
+    def _digest(self, body):
+        class_name = type(self).__name__.encode('utf-8')
+        sha = pkg_digest.copy()
+        sha.update(body.encode('utf-8', 'ignore'))
+        sha.update(class_name)
+        return sha.hexdigest()
+
+    def _compile(self, program, builtins):
+        compiler = Compiler(self.engine, program, builtins, strict=self.strict)
+        return compiler.code
+
+    def _make(self, body, builtins):
+        program = self.parse(body)
+        module = Module("initialize", program)
+        return self._compile(module, builtins)
+
+
+class BaseTemplateFile(BaseTemplate):
+    """File-based template base class.
+
+    Relative path names are supported only when a template loader is
+    provided as the ``loader`` parameter.
+    """
+
+    # Auto reload is not enabled by default because it's a significant
+    # performance hit
+    auto_reload = AUTO_RELOAD
+
+    def __init__(self, filename, auto_reload=None, **config):
+        # Normalize filename
+        filename = os.path.abspath(
+            os.path.normpath(os.path.expanduser(filename))
+            )
+
+        self.filename = filename
+
+        # Override reload setting only if value is provided explicitly
+        if auto_reload is not None:
+            self.auto_reload = auto_reload
+
+        super(BaseTemplateFile, self).__init__(**config)
+
+        if EAGER_PARSING:
+            self.cook_check()
+
+    def cook_check(self):
+        if self.auto_reload:
+            mtime = self.mtime()
+
+            if mtime != self._v_last_read:
+                self._v_last_read = mtime
+                self._cooked = False
+
+        if self._cooked is False:
+            body = self.read()
+            log.debug("cooking %r (%d bytes)..." % (self.filename, len(body)))
+            self.cook(body)
+
+    def mtime(self):
+        try:
+            return os.path.getmtime(self.filename)
+        except (IOError, OSError):
+            return 0
+
+    def read(self):
+        with open(self.filename, "rb") as f:
+            data = f.read()
+
+        body, encoding, content_type = read_bytes(
+            data, self.default_encoding
+            )
+
+        # In non-XML mode, we support various platform-specific line
+        # endings and convert them to the UNIX newline character
+        if content_type != "text/xml" and '\r' in body:
+            body = body.replace('\r\n', '\n').replace('\r', '\n')
+
+        self.content_type = content_type
+        self.content_encoding = encoding
+
+        return body
+
+    def _get_module_name(self, digest):
+        filename = os.path.basename(self.filename)
+        mangled = mangle(filename)
+        return "%s_%s.py" % (mangled, digest)
+
+    def _get_filename(self):
+        return self.__dict__.get('filename')
+
+    def _set_filename(self, filename):
+        self.__dict__['filename'] = filename
+        self._v_last_read = None
+        self._cooked = False
+
+    filename = property(_get_filename, _set_filename)
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/__init__.py b/lib3/Chameleon-2.9.2/src/chameleon/tests/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/__init__.py
@@ -0,0 +1,1 @@
+#
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-interpolation.txt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-interpolation.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-interpolation.txt
@@ -0,0 +1,1 @@
+${'<Hello world>'}<&>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-variable-scope.html b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-variable-scope.html
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-variable-scope.html
@@ -0,0 +1,7 @@
+<html>
+  <body py:with="text 'Hello world!'">
+    ${text}
+    $text
+  </body>
+  ${text | 'Goodbye world!'}
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-variable-scope.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-variable-scope.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001-variable-scope.pt
@@ -0,0 +1,11 @@
+<html>
+  <body tal:define="text 'Hello world!'">
+    ${text}
+  </body>
+  <tal:check condition="exists: text">
+    bad
+  </tal:check>
+  <tal:check condition="not: exists: text">
+    ok
+  </tal:check>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/001.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/002-repeat-scope.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/002-repeat-scope.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/002-repeat-scope.pt
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <div tal:repeat="text ('Hello', 'Goodbye')">
+      <span tal:repeat="char ('!', '.')">${text}${char}</span>
+    </div>
+    <tal:check condition="not: exists: text">ok</tal:check>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/002.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/002.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/002.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc ></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/003-content.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/003-content.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/003-content.pt
@@ -0,0 +1,17 @@
+<html>
+  <body>
+    <div tal:content="'Hello world!'" />
+    <div tal:content="'Hello world!'" />1
+   2<div tal:content="'Hello world!'" />
+    <div tal:content="'Hello world!'" />3
+    <div tal:content="'Hello world!'">4</div>5
+   6<div tal:content="'Hello world!'"></div>
+    <div tal:content="1" />
+    <div tal:content="1.0" />
+    <div tal:content="True" />
+    <div tal:content="False" />
+    <div tal:content="0" />
+    <div tal:content="None" />
+    <div tal:replace="content" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/003.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/003.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/003.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc >
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/004-attributes.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/004-attributes.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/004-attributes.pt
@@ -0,0 +1,18 @@
+<html>
+  <body>
+    <span tal:attributes="class 'hello'" />
+    <span class="goodbye" tal:attributes="class 'hello'" />
+    <span CLASS="goodbye" tal:attributes="class 'hello'" />
+    <span tal:attributes="class None" />
+    <span a="1" b="2" c="3" tal:attributes="a None" />
+    <span a="1" b="2" c="3" tal:attributes="b None" />
+    <span a="1" b="2" c="3" tal:attributes="c None" />
+    <span a="1" b="2" c="3" tal:attributes="b None; c None" />
+    <span a="1" b="2" c="3" tal:attributes="b string:;;" />
+    <span a="1" b="2" c="3" tal:attributes="b string:&" />
+    <span class="hello" tal:attributes="class 'goodbye'" />
+    <span class="hello" tal:attributes="class '"goodbye"'" />
+    <span class="hello" tal:attributes="class '\'goodbye\''" />
+    <span class='hello' tal:attributes="class '\'goodbye\''" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/004.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/004.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/004.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA #IMPLIED>
+]>
+<doc a1="v1"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/005-default.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/005-default.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/005-default.pt
@@ -0,0 +1,12 @@
+<html>
+  <body>
+    <img class="default" tal:attributes="class default" />
+    <img tal:attributes="class default" />
+    <span tal:content="default">Default</span>
+    <span tal:content="True">Default</span>
+    <span tal:content="False">Default</span>
+    <span tal:content="default">
+      <em>${'Computed default'}</em>
+    </span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/005.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/005.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/005.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA #IMPLIED>
+]>
+<doc a1 = "v1"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/006-attribute-interpolation.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/006-attribute-interpolation.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/006-attribute-interpolation.pt
@@ -0,0 +1,9 @@
+<html>
+  <body class="ltr" tal:define="hash string:#">
+    <img src="${'#'}" alt="copyright (c) ${2010}" />
+    <img src="" alt="copyright (c) ${2010}" tal:attributes="src string:$hash" />
+    <img src="" alt="copyright (c) ${2010}" tal:attributes="src string:${hash}" />
+    <img src="${None}" alt="$ignored" />
+    <img src="" alt="${'%stype \'str\'%s' % (chr(60), chr(62))}" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/006.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/006.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/006.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA #IMPLIED>
+]>
+<doc a1='v1'></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/007-content-interpolation.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/007-content-interpolation.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/007-content-interpolation.pt
@@ -0,0 +1,15 @@
+<html>
+  <body>
+    ${'Hello world!'}
+    ${literal}
+    ${structure: literal.s}
+    ${"%stype 'str'%s" % (chr(60), chr(62))}
+    &&
+    ${None}
+    ${None or
+      'Hello world'}
+    $leftalone
+    <div>${None}</div>
+    <div>${1 < 2 and 'Hello world' or None}</div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/007.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/007.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/007.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc> </doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/008-builtins.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/008-builtins.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/008-builtins.pt
@@ -0,0 +1,11 @@
+<html>
+  <body>
+    ${nothing}
+    <div tal:attributes="class string:dynamic" class="static">
+      ${attrs['class']}
+    </div>
+    <div tal:define="nothing string:nothing">
+      ${nothing}
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/008.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/008.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/008.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>&<>"'</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/009-literals.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/009-literals.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/009-literals.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    ${literal}
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/009.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/009.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/009.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>&#x20;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/010-structure.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/010-structure.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/010-structure.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    <div tal:content="text string:1 < 2" />
+    <div tal:content="structure string:2 < 3, 2&3, 2<3, 2>3" />
+    <div tal:content="structure string:3 ${'<'} 4" />
+    <div tal:content="structure '%d < %d' % (4, 5)" />
+    <div tal:replace="structure content" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/010.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/010.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/010.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA #IMPLIED>
+]>
+<doc a1="v1" ></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/011-messages.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/011-messages.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/011-messages.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    <div tal:content="text message" />
+    <div tal:content="structure message" />
+    <div tal:content="text string:${message}" />
+    <div tal:content="structure string:${message}" />
+    ${message}
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/011.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/011.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/011.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA #IMPLIED a2 CDATA #IMPLIED>
+]>
+<doc a1="v1" a2="v2"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/012-translation.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/012-translation.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/012-translation.pt
@@ -0,0 +1,21 @@
+<html>
+  <body>
+    <div i18n:translate="">
+      Hello world!
+    </div>
+    <div i18n:translate="hello_world">
+      Hello world!
+    </div>
+    <div i18n:translate="">
+      <sup>Hello world!</sup>
+    </div>
+    <div i18n:translate="">
+      Hello <em i18n:name="first">${'world'}</em>!
+      Goodbye <em i18n:name="second">${'planet'}</em>!
+    </div>
+    <div i18n:translate="hello_goodbye">
+      Hello <em i18n:name="first">${'world'}</em>!
+      Goodbye <em i18n:name="second">${'planet'}</em>!
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/012.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/012.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/012.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc : CDATA #IMPLIED>
+]>
+<doc :="v1"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/013-repeat-nested.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/013-repeat-nested.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/013-repeat-nested.pt
@@ -0,0 +1,11 @@
+<html>
+  <body>
+    <table>
+      <tr tal:repeat="i (1,2)">
+        <td tal:repeat="j (1,2)">
+          [${i},${j}]
+        </td>
+      </tr>
+    </table>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/013.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/013.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/013.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc _.-0123456789 CDATA #IMPLIED>
+]>
+<doc _.-0123456789="v1"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/014-repeat-nested-similar.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/014-repeat-nested-similar.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/014-repeat-nested-similar.pt
@@ -0,0 +1,7 @@
+<html>
+  <body>
+    <span tal:repeat="i (3,4)">
+      <span tal:repeat="j (3,4)">[${i},${j}]</span>
+    </span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/014.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/014.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/014.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc abcdefghijklmnopqrstuvwxyz CDATA #IMPLIED>
+]>
+<doc abcdefghijklmnopqrstuvwxyz="v1"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/015-translation-nested.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/015-translation-nested.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/015-translation-nested.pt
@@ -0,0 +1,10 @@
+<html>
+  <body>
+    <div i18n:translate="">
+      Price:
+      <span i18n:name="price" i18n:translate="">
+        Per kilo <em i18n:name="amount">${12.5}</em>
+      </span>
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/015.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/015.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/015.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc ABCDEFGHIJKLMNOPQRSTUVWXYZ CDATA #IMPLIED>
+]>
+<doc ABCDEFGHIJKLMNOPQRSTUVWXYZ="v1"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/016-explicit-translation.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/016-explicit-translation.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/016-explicit-translation.pt
@@ -0,0 +1,11 @@
+<html>
+  <body>
+    <div i18n:translate="" tal:content="string:Hello world!">
+      Hello world!
+    </div>
+    <img alt="${'Hello world!'}" i18n:attributes="alt" />
+    <img alt="${'Hello world!'}" i18n:attributes="alt hello_world" />
+    <img tal:attributes="alt 'Hello world!'" i18n:attributes="alt" />
+    <img tal:attributes="alt 'Hello world!'" i18n:attributes="alt hello_world" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/016.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/016.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/016.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><?pi?></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/017-omit-tag.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/017-omit-tag.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/017-omit-tag.pt
@@ -0,0 +1,12 @@
+<html>
+  <body>
+    <div tal:omit-tag="">Hello world!</div>
+    <div tal:omit-tag="">1
+      Hello world!
+   2</div>3
+   4<div tal:omit-tag="True">Hello world!</div>
+    <div tal:omit-tag="False">Hello world!</div>
+    <div class="omitted" tal:omit-tag="True">Hello world!</div>
+    <div class="${'omitted'}" tal:omit-tag="True">Hello world!</div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/017.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/017.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/017.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><?pi some data ? > <??></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/018-translation-nested-dynamic.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/018-translation-nested-dynamic.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/018-translation-nested-dynamic.pt
@@ -0,0 +1,13 @@
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:i18n="http://xml.zope.org/namespaces/i18n">
+  <div i18n:translate="" tal:omit-tag="">
+      <span i18n:name="monthname"
+            i18n:translate=""
+            tal:content="'october'"
+            tal:omit-tag="">monthname</span>
+      <span i18n:name="year"
+            i18n:translate=""
+            tal:content="1982"
+            tal:omit-tag="">year</span>
+  </div>
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/018.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/018.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/018.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><![CDATA[<foo>]]></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/019-replace.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/019-replace.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/019-replace.pt
@@ -0,0 +1,13 @@
+<html>
+  <body>
+    <div tal:replace="'Hello world!'" />
+    <div tal:replace="'Hello world!'" />1
+   2<div tal:replace="'Hello world!'" />
+    <div tal:replace="'Hello world!'" />3
+    <div tal:replace="'Hello world!'">4</div>5
+   6<div tal:replace="'Hello world!'"></div>
+    <div tal:replace="1" />
+    <div tal:replace="1.0" />
+    <div tal:replace="True" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/019.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/019.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/019.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><![CDATA[<&]]></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/020-on-error.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/020-on-error.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/020-on-error.pt
@@ -0,0 +1,10 @@
+<html>
+  <body>
+    <div id="test" tal:attributes="class python: 'abc' + 2" tal:on-error="nothing" />
+    <div tal:on-error="string:${type(error.value).__name__} thrown at ${error.lineno}:${error.offset}.">
+      <div tal:content="undefined" />
+    </div>
+    <div tal:replace="undefined" tal:on-error="nothing" />
+    <div tal:content="undefined" tal:on-error="nothing" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/020.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/020.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/020.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><![CDATA[<&]>]]]></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/021-translation-domain.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/021-translation-domain.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/021-translation-domain.pt
@@ -0,0 +1,16 @@
+<html>
+  <body i18n:domain="old">
+    <div i18n:domain="new" i18n:translate="">
+      Hello world!
+    </div>
+    <div i18n:translate="">
+      Hello world!
+    </div>
+    <div class="test" i18n:domain="new" i18n:attributes="class">
+      Hello world!
+    </div>
+    <div class="test" i18n:domain="new" i18n:attributes="class test_msgid">
+      Hello world!
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/021.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/021.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/021.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><!-- a comment --></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/022-switch.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/022-switch.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/022-switch.pt
@@ -0,0 +1,13 @@
+<html>
+  <body>
+    <div tal:switch="True">
+      <span tal:case="False">bad</span>
+      <span tal:case="True">ok</span>
+      <span tal:case="not not True">ok</span>
+    </div>
+    <div tal:switch="True">
+      <span tal:case="False">bad</span>
+      <span tal:case="default">ok</span>
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/022.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/022.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/022.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><!-- a comment ->--></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/023-condition.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/023-condition.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/023-condition.pt
@@ -0,0 +1,6 @@
+<html>
+  <body tal:condition="True">
+    <span tal:define="selector False" tal:condition="selector">bad</span>
+    <span tal:condition="True">ok</span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/023.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/023.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/023.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY e "">
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/024-namespace-elements.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/024-namespace-elements.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/024-namespace-elements.pt
@@ -0,0 +1,16 @@
+<html>
+  <body>
+    <tal:first>
+      <tal:second>
+        ${'first'}
+      </tal:second>
+      second
+    </tal:first>
+    <tal:block condition="True">
+      ok
+    </tal:block>
+    <tal:block condition="False">
+      bad
+    </tal:block>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/024.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/024.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/024.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (foo)>
+<!ELEMENT foo (#PCDATA)>
+<!ENTITY e "<foo></foo>">
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/025-repeat-whitespace.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/025-repeat-whitespace.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/025-repeat-whitespace.pt
@@ -0,0 +1,14 @@
+<html>
+  <body>
+    <ul>
+      <tal:item repeat="i (1, 2, 3)"><li tal:content="i" /></tal:item>
+      <span tal:omit-tag="" tal:repeat="j (1, 2, 3)"><li tal:content="j" /></span>
+      <tal:count>
+        <tal:count-loop repeat="count (1, 2, 3)">
+          <span tal:replace="count"
+                /><tal:comma condition="not repeat['count'].end">,</tal:comma>
+       </tal:count-loop>
+      </tal:count>.
+    </ul>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/025.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/025.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/025.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (foo*)>
+<!ELEMENT foo (#PCDATA)>
+]>
+<doc><foo/><foo></foo></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/026-repeat-variable.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/026-repeat-variable.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/026-repeat-variable.pt
@@ -0,0 +1,13 @@
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:tal="http://xml.zope.org/namespaces/tal">
+  <ul>
+    <li tal:attributes="class repeat['i'].even()+repeat['i'].odd()" name="${i}-${repeat.i.index}" tal:repeat="i range(3)"><span tal:replace="i" /></li>
+  </ul>
+  <ul>
+    <li tal:attributes="class repeat['i'].even+repeat['i'].odd"
+        tal:repeat="i range(3)"><span tal:replace="i" /></li>
+  </ul>
+  <ul>
+    <li tal:repeat="i range(3)"><span tal:condition="repeat['i'].even" tal:replace="repeat['i'].even" /><span tal:condition="repeat['i'].odd" tal:replace="repeat['i'].odd" /></li>
+  </ul>
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/026.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/026.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/026.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (foo*)>
+<!ELEMENT foo EMPTY>
+]>
+<doc><foo/><foo></foo></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/027-attribute-replacement.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/027-attribute-replacement.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/027-attribute-replacement.pt
@@ -0,0 +1,11 @@
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:tal="http://xml.zope.org/namespaces/tal">
+  <span id="test"
+        class="dummy"
+        onClick=""
+        tal:define="a 'abc'"
+        tal:attributes="class 'def' + a + default; style 'hij'; onClick 'alert();;'"
+        tal:content="a + 'ghi'" />
+  <span tal:replace="'Hello World!'">Hello <b>Universe</b>!</span>
+  <span tal:replace="'Hello World!'"><b>Hello Universe!</b></span>
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/027.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/027.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/027.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (foo*)>
+<!ELEMENT foo ANY>
+]>
+<doc><foo/><foo></foo></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/028-attribute-toggle.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/028-attribute-toggle.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/028-attribute-toggle.pt
@@ -0,0 +1,6 @@
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:tal="http://xml.zope.org/namespaces/tal">
+  <option tal:attributes="selected True"></option>
+  <option tal:attributes="selected False"></option>
+  <option tal:attributes="selected None"></option>
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/028.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/028.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/028.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/029-attribute-ordering.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/029-attribute-ordering.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/029-attribute-ordering.pt
@@ -0,0 +1,5 @@
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:tal="http://xml.zope.org/namespaces/tal">
+  <a rel="self" href="http://repoze.org" id="link-id"
+     tal:attributes="href 'http://python.org'" />
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/029.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/029.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/029.xml
@@ -0,0 +1,5 @@
+<?xml version='1.0'?>
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/030-repeat-tuples.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/030-repeat-tuples.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/030-repeat-tuples.pt
@@ -0,0 +1,7 @@
+<html>
+  <body>
+    <div tal:repeat="(i, j) ((1, 2), (3, 4))">
+      ${repeat['i', 'j'].number}, ${i}, ${j}
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/030.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/030.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/030.xml
@@ -0,0 +1,5 @@
+<?xml version = "1.0"?>
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/031-namespace-with-tal.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/031-namespace-with-tal.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/031-namespace-with-tal.pt
@@ -0,0 +1,7 @@
+<div>
+  <tal:example replace="'Hello World!'" />
+  <tal:example tal:replace="'Hello World!'" />
+  <tal:div content="'Hello World!'" />
+  <tal:multiple repeat="i range(3)" replace="i" />
+  <tal:div condition="True">True</tal:div>
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/031.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/031.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/031.xml
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/032-master-template.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/032-master-template.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/032-master-template.pt
@@ -0,0 +1,20 @@
+<html i18n:domain="master" metal:define-macro="main" tal:define="content nothing">
+  <head>
+    <title metal:define-slot="title"
+           metal:define-macro="title"
+           tal:define="has_title exists: title"
+           tal:content="title if has_title else default">Master template</title>
+  </head>
+  <body>
+    <div id="content">
+      <metal:content define-slot="content">
+        <!-- content here -->
+      </metal:content>
+    </div>
+    <div id="footer">
+      <metal:footer define-slot="body-footer" tal:content="nothing">
+        <!-- footer here -->
+      </metal:footer>
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/032.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/032.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/032.xml
@@ -0,0 +1,5 @@
+<?xml version='1.0' standalone='yes'?>
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/033-use-macro-trivial.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/033-use-macro-trivial.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/033-use-macro-trivial.pt
@@ -0,0 +1,1 @@
+<html metal:use-macro="load('032-master-template.pt').macros['main']" />
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/033.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/033.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/033.xml
@@ -0,0 +1,5 @@
+<?xml version='1.0' encoding="UTF-8" standalone='yes'?>
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/034-use-template-as-macro.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/034-use-template-as-macro.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/034-use-template-as-macro.pt
@@ -0,0 +1,1 @@
+<html metal:use-macro="load('032-master-template.pt')" />
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/034.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/034.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/034.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc/>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/035-use-macro-with-fill-slot.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/035-use-macro-with-fill-slot.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/035-use-macro-with-fill-slot.pt
@@ -0,0 +1,5 @@
+<html metal:use-macro="load('032-master-template.pt').macros['main']">
+  <title metal:fill-slot="title" tal:define="kind 'New'">
+    ${kind} title
+  </title>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/035.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/035.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/035.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc />
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/036-use-macro-inherits-dynamic-scope.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/036-use-macro-inherits-dynamic-scope.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/036-use-macro-inherits-dynamic-scope.pt
@@ -0,0 +1,2 @@
+<html tal:define="title string:New title"
+      metal:use-macro="load('032-master-template.pt').macros['main']" />
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/036.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/036.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/036.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
+<?pi data?>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/037-use-macro-local-variable-scope.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/037-use-macro-local-variable-scope.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/037-use-macro-local-variable-scope.pt
@@ -0,0 +1,5 @@
+<html metal:use-macro="load('032-master-template.pt').macros['main']" >
+  <metal:content metal:fill-slot="content">
+    <span tal:condition="content is None">ok</span>
+  </metal:content>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/037.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/037.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/037.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
+<!-- comment -->
+
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/038-use-macro-globals.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/038-use-macro-globals.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/038-use-macro-globals.pt
@@ -0,0 +1,6 @@
+<metal:globals use-macro="load('039-globals.pt')"  />
+<html>
+  <body>
+    <span tal:condition="content is None">ok</span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/038.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/038.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/038.xml
@@ -0,0 +1,6 @@
+<!-- comment -->
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
+
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/039-globals.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/039-globals.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/039-globals.pt
@@ -0,0 +1,1 @@
+<tal:globals define="global content None" />
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/039.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/039.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/039.xml
@@ -0,0 +1,5 @@
+<?pi data?>
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/040-macro-using-template-symbol.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/040-macro-using-template-symbol.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/040-macro-using-template-symbol.pt
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal"
+      metal:define-macro="master"
+      template-macros="${' '.join(template.macros.names)}"
+      macros="${' '.join(macros.names)}">
+    <metal:block tal:define="foo 'foo'">
+      ${foo}
+      <div metal:define-slot="content" tal:replace="None">
+         <!-- will be replaced -->
+      </div>
+      <span template-macros="${' '.join(template.macros.names)}"
+            macros="${' '.join(macros.names)}">
+         <!-- demonstrate difference between
+              `template` and `macros` symbol -->
+      </span>
+    </metal:block>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/040.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/040.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/040.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA #IMPLIED>
+]>
+<doc a1=""<&>'"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/041-translate-nested-names.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/041-translate-nested-names.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/041-translate-nested-names.pt
@@ -0,0 +1,22 @@
+<html>
+  <body>
+    <div i18n:translate="">
+      Hello
+      <tal:nested condition="True">
+        <span i18n:name="world">world!</span>
+      </tal:nested>
+    </div>
+    <div i18n:translate="hello">
+      Hello
+      <tal:nested condition="True">
+        <span i18n:name="world">world!</span>
+      </tal:nested>
+    </div>
+    <div i18n:translate="">
+      Goodbye
+      <tal:nested condition="False">
+        <span i18n:name="world">world!</span>
+      </tal:nested>
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/041.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/041.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/041.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA #IMPLIED>
+]>
+<doc a1="A"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/042-use-macro-fill-footer.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/042-use-macro-fill-footer.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/042-use-macro-fill-footer.pt
@@ -0,0 +1,3 @@
+<html metal:use-macro="load('032-master-template.pt').macros['main']">
+  <metal:footer fill-slot="body-footer">New footer</metal:footer>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/042.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/042.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/042.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>A</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/043-macro-nested-dynamic-vars.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/043-macro-nested-dynamic-vars.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/043-macro-nested-dynamic-vars.pt
@@ -0,0 +1,19 @@
+<html>
+  <body>
+    <tal:macros condition="0">
+
+      <metal:outer define-macro="outer">
+        <metal:inner use-macro="template.macros['inner']" />
+      </metal:outer>
+
+      <metal:inner define-macro="inner">
+        ${title}
+      </metal:inner>
+
+    </tal:macros>
+
+    <div tal:define="title string:My title"
+         metal:use-macro="template.macros['outer']"
+         />
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/043.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/043.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/043.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ATTLIST doc a1 CDATA #IMPLIED>
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc a1="foo
+bar"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/044-tuple-define.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/044-tuple-define.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/044-tuple-define.pt
@@ -0,0 +1,5 @@
+<html>
+  <body tal:define="(a, b) 'a', 'b'">
+    ${a}, ${b}
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/044.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/044.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/044.xml
@@ -0,0 +1,10 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (e*)>
+<!ELEMENT e EMPTY>
+<!ATTLIST e a1 CDATA "v1" a2 CDATA "v2" a3 CDATA #IMPLIED>
+]>
+<doc>
+<e a3="v3"/>
+<e a1="w1"/>
+<e a2="w2" a3="v3"/>
+</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/045-namespaces.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/045-namespaces.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/045-namespaces.pt
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE application [
+  <!ENTITY nbsp "\ ">
+]>
+<application xmlns="http://research.sun.com/wadl/2006/10"
+             xsi:schemaLocation="http://research.sun.com/wadl/2006/10/wadl.xsd"
+             xmlns:wadl="http://research.sun.com/wadl/2006/10"
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xmlns:tal="http://xml.zope.org/namespaces/tal">
+  <resources tal:define="path '/'">
+    <resource path="${path}">ZZZ YYY XXX</resource>
+  </resources>
+</application>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/045.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/045.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/045.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA "v1">
+<!ATTLIST doc a1 CDATA "z1">
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/046-extend-macro.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/046-extend-macro.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/046-extend-macro.pt
@@ -0,0 +1,6 @@
+<html metal:define-macro="extended"
+      metal:extend-macro="load('032-master-template.pt').macros['main']">
+  <metal:footer fill-slot="body-footer">
+    <span metal:define-slot="kind">New</span> footer
+  </metal:footer>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/046.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/046.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/046.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA "v1">
+<!ATTLIST doc a2 CDATA "v2">
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/047-use-extended-macro.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/047-use-extended-macro.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/047-use-extended-macro.pt
@@ -0,0 +1,3 @@
+<html metal:use-macro="load('046-extend-macro.pt').macros['extended']">
+  <em metal:fill-slot="kind">Extended</em>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/047.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/047.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/047.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>X
+Y</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/048-use-extended-macro-fill-original.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/048-use-extended-macro-fill-original.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/048-use-extended-macro-fill-original.pt
@@ -0,0 +1,5 @@
+<html metal:use-macro="load('046-extend-macro.pt').macros['extended']">
+  <metal:footer fill-slot="body-footer">
+    Extended footer
+  </metal:footer>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/048.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/048.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/048.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>]</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/049-entities-in-attributes.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/049-entities-in-attributes.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/049-entities-in-attributes.pt
@@ -0,0 +1,11 @@
+<html>
+  <body>
+    <pre tal:content="string:amp=&amp; lt=&lt;"  />
+    <pre tal:content="structure string:amp=&amp; lt=&lt;"  />
+    <script tal:replace="structure string:<script />" />
+    <script tal:replace="string:<script />" />
+    <script tal:replace="string:${'<'}script /${'>'}" />
+    <script tal:replace="structure string:${'<'}script /${'>'}" />
+    <img alt="1 < 2: ${1 < 2}" />
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/049.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/049.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c3cc797b5954881cc794f6720674a8bfa13aacbe
GIT binary patch
[stripped]
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/050-define-macro-and-use-not-extend.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/050-define-macro-and-use-not-extend.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/050-define-macro-and-use-not-extend.pt
@@ -0,0 +1,6 @@
+<html metal:define-macro="main"
+      metal:use-macro="load('032-master-template.pt').macros['main']">
+  <metal:content fill-slot="content">
+     Default content
+  </metal:content>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/050.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/050.xml
new file mode 100644
index 0000000000000000000000000000000000000000..12303b1af2185eb29894629b99431fea831367b1
GIT binary patch
[stripped]
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/051-use-non-extended-macro.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/051-use-non-extended-macro.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/051-use-non-extended-macro.pt
@@ -0,0 +1,5 @@
+<html metal:use-macro="load('050-define-macro-and-use-not-extend.pt').macros['main']">
+  <metal:content fill-slot="content">
+    <span>Filled content</span>
+  </metal:content>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/051.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/051.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7ae8f6c73a4b47ec18492ebefed16c63f5f5ef22
GIT binary patch
[stripped]
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/052-i18n-domain-inside-filled-slot.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/052-i18n-domain-inside-filled-slot.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/052-i18n-domain-inside-filled-slot.pt
@@ -0,0 +1,8 @@
+<html metal:define-macro="main"
+      metal:use-macro="load('032-master-template.pt').macros['main']">
+  <metal:content fill-slot="content">
+    <span i18n:domain="mydomain" i18n:translate="">
+       Translated content
+    </span>
+  </metal:content>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/052.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/052.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/052.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>𐀀􏿽</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/053-special-characters-in-attributes.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/053-special-characters-in-attributes.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/053-special-characters-in-attributes.pt
@@ -0,0 +1,6 @@
+<html>
+  <body>
+    <a tal:attributes="href string:@@view">test</a>
+    <a href="${'@@'}view">test</a>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/053.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/053.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/053.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ENTITY e "<e/>">
+<!ELEMENT doc (e)>
+<!ELEMENT e EMPTY>
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/054-import-expression.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/054-import-expression.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/054-import-expression.pt
@@ -0,0 +1,3 @@
+<div tal:define="datetime import: datetime.datetime">
+  ${datetime(1984, 12, 31).isoformat()}
+</div>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/054.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/054.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/054.xml
@@ -0,0 +1,10 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+
+
+<doc
+></doc
+>
+
+
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/055-attribute-fallback-to-dict-lookup.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/055-attribute-fallback-to-dict-lookup.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/055-attribute-fallback-to-dict-lookup.pt
@@ -0,0 +1,4 @@
+<div tal:define="obj {'foo': 'bar', 'boo': {'bar': 'baz'}}">
+  ${obj.foo}
+  ${obj.boo.bar}
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/055.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/055.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/055.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<?pi  data?>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/056-comment-attribute.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/056-comment-attribute.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/056-comment-attribute.pt
@@ -0,0 +1,7 @@
+<html>
+  <body>
+    <tal:first comment="ignored">
+      Namespace tag
+    </tal:first>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/056.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/056.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/056.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>&#x0000000000000000000000000000000000000041;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/057-order.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/057-order.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/057-order.pt
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <div tal:condition="False" tal:repeat="item bad_input" />
+    <div tal:define="sequence 1, 2, 3"
+         tal:repeat="item sequence"
+         tal:replace="item" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/057.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/057.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/057.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (a*)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/058-script.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/058-script.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/058-script.pt
@@ -0,0 +1,16 @@
+<html>
+  <head>
+    <script tal:define="field {'oid': 1}; values 'values'; options 'options'">
+      deform.addCallback(
+        '${field.oid}',
+        function (oid) {
+            $('#' + oid).autocomplete({source: ${values}});
+            $('#' + oid).autocomplete("option", ${options});
+        }
+      );
+    </script>
+  </head>
+  <body>
+    <!-- Form -->
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/058.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/058.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/058.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ATTLIST doc a1 NMTOKENS #IMPLIED>
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc a1=" 1  	2 	"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/059-embedded-javascript.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/059-embedded-javascript.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/059-embedded-javascript.pt
@@ -0,0 +1,6 @@
+<html>
+  <body>
+    <span onclick="alert(true && false);">test</span>
+    <span onclick="alert(${str(True).lower()} && ${str(False).lower()});">test</span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/059.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/059.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/059.xml
@@ -0,0 +1,10 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (e*)>
+<!ELEMENT e EMPTY>
+<!ATTLIST e a1 CDATA #IMPLIED a2 CDATA #IMPLIED a3 CDATA #IMPLIED>
+]>
+<doc>
+<e a1="v1" a2="v2" a3="v3"/>
+<e a1="w1" a2="v2"/>
+<e a1="v1" a2="w2" a3="v3"/>
+</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/060-macro-with-multiple-same-slots.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/060-macro-with-multiple-same-slots.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/060-macro-with-multiple-same-slots.pt
@@ -0,0 +1,8 @@
+<html metal:define-macro="main">
+  <head>
+    <title><metal:title define-slot="title">Untitled</metal:title></title>
+  </head>
+  <body>
+    <h1><metal:title define-slot="title">Untitled</metal:title></h1>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/060.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/060.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/060.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>X
Y</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/061-fill-one-slot-but-two-defined.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/061-fill-one-slot-but-two-defined.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/061-fill-one-slot-but-two-defined.pt
@@ -0,0 +1,3 @@
+<html metal:use-macro="load('060-macro-with-multiple-same-slots.pt').macros['main']">
+  <metal:title fill-slot="title">My document</metal:title>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/061.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/061.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/061.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>£</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/062-comments-and-expressions.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/062-comments-and-expressions.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/062-comments-and-expressions.pt
@@ -0,0 +1,27 @@
+<div>
+  <!--! ${dropped} -->
+</div>
+
+<div>
+  <!--? ${left alone} -->
+</div>
+
+<div>
+  <!-- ${'not left alone'} -->
+</div>
+
+<div meta:interpolation="true">
+  <!-- ${'not left alone'} -->
+</div>
+
+<div meta:interpolation="false">
+  <!-- ${left alone} -->
+</div>
+
+<!--[if IE ${6}]>
+  Special instructions for IE 6 here
+<![endif]-->
+
+<!--?[if IE 6]>
+  ${left alone}
+<![endif]-->
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/062.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/062.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/062.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>&#xe40;&#xe08;&#xe21;ส์</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/063-continuation.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/063-continuation.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/063-continuation.pt
@@ -0,0 +1,4 @@
+<div tal:define="foo 1 + \
+                     1">
+  ${foo}
+</div>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/063.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/063.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/063.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE เจมส์ [
+<!ELEMENT เจมส์ (#PCDATA)>
+]>
+<เจมส์></เจมส์>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/064-tags-and-special-characters.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/064-tags-and-special-characters.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/064-tags-and-special-characters.pt
@@ -0,0 +1,4 @@
+<tal:block>
+  <div	id="test"	class="${'test'}">
+  </div>
+</tal:block>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/064.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/064.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/064.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>&#x10000;&#x10FFFD;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/065-use-macro-in-fill.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/065-use-macro-in-fill.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/065-use-macro-in-fill.pt
@@ -0,0 +1,6 @@
+<html metal:use-macro="load('032-master-template.pt').macros['main']">
+  <title tal:define="title string:Title"
+         metal:fill-slot="title"
+         metal:use-macro="load('032-master-template.pt').macros['title']" />
+  <div metal:fill-slot="content">Content</div>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/065.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/065.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/065.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ENTITY e "<">
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/066-load-expression.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/066-load-expression.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/066-load-expression.pt
@@ -0,0 +1,1 @@
+<html tal:define="hello_world load: hello_world.pt" metal:use-macro="hello_world" />
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/066.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/066.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/066.xml
@@ -0,0 +1,7 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA #IMPLIED>
+<!-- 34 is double quote -->
+<!ENTITY e1 """>
+]>
+<doc a1="&e1;"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/067-attribute-decode.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/067-attribute-decode.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/067-attribute-decode.pt
@@ -0,0 +1,6 @@
+<html>
+  <body>
+    <img src="#" tal:attributes="class 1 > 0 and 'up' or 0 < 1 and 'down';" />
+    <img src="#" tal:attributes="class 0 > 1 and 'up' or 0 < 1 and 'down';" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/067.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/067.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/067.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>
</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/068-less-than-greater-than-in-attributes.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/068-less-than-greater-than-in-attributes.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/068-less-than-greater-than-in-attributes.pt
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <span tal:content="string:0 < 1 or 0 > 1" />
+    <span tal:content="structure string:0 < 1 or 0 > 1" />
+    <span class="0 < 1 or 0 > 1" />
+    <span>0 < 1 or 0 > 1</span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/068.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/068.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/068.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY e "
">
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/069-translation-domain-and-macro.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/069-translation-domain-and-macro.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/069-translation-domain-and-macro.pt
@@ -0,0 +1,3 @@
+<html metal:use-macro="load('032-master-template.pt').macros['main']">
+  <title metal:fill-slot="title" i18n:domain="test" i18n:translate="title">Title</title>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/069.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/069.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/069.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!NOTATION n PUBLIC "whatever">
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/070-translation-domain-and-use-macro.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/070-translation-domain-and-use-macro.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/070-translation-domain-and-use-macro.pt
@@ -0,0 +1,3 @@
+<html i18n:domain="test" metal:use-macro="load('032-master-template.pt').macros['main']">
+  <title metal:fill-slot="title" i18n:translate="title">Title</title>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/070.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/070.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/070.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ENTITY % e "<!ELEMENT doc (#PCDATA)>">
+%e;
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/071-html-attribute-defaults.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/071-html-attribute-defaults.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/071-html-attribute-defaults.pt
@@ -0,0 +1,11 @@
+<html>
+  <body>
+    <input type="input" tal:attributes="checked True" />
+    <input type="input" tal:attributes="checked False" />
+    <input type="input" tal:attributes="checked None" />
+    <input type="input" checked="checked" tal:attributes="checked default" />
+    <input type="input" checked tal:attributes="checked default" />
+    <input type="input" tal:attributes="checked default" />
+    <input type="input" class="field" tal:attributes="class True" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/071.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/071.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/071.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a ID #IMPLIED>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/072-repeat-interpolation.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/072-repeat-interpolation.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/072-repeat-interpolation.pt
@@ -0,0 +1,13 @@
+<html>
+  <body>
+    <ul>
+      <li tal:repeat="i range(1, 4)" class="${'odd' if i % 2 != 0 else default}">${i}</li>
+    </ul>
+    <ul>
+      <li tal:repeat="i range(1, 4)" class="${'odd' if i % 2 != 0 else None}">${i}</li>
+    </ul>
+    <ul>
+      <li tal:repeat="i range(1, 4)" class="${'odd' if i % 2 != 0 else False}">${i}</li>
+    </ul>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/072.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/072.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/072.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a IDREF #IMPLIED>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/073-utf8-encoded.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/073-utf8-encoded.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/073-utf8-encoded.pt
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title>${'my title'} — ${'my site'}</title></head>
+<body></body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/073.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/073.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/073.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a IDREFS #IMPLIED>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/074-encoded-template.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/074-encoded-template.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/074-encoded-template.pt
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="windows-1251" ?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title>${'my title'} — ${'my site'}</title></head>
+<body></body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/074.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/074.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/074.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a ENTITY #IMPLIED>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/075-nested-macros.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/075-nested-macros.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/075-nested-macros.pt
@@ -0,0 +1,11 @@
+<metal:page define-macro="master">
+  <tal:block metal:use-macro="load('032-master-template.pt').macros['main']">
+
+    <metal:block fill-slot="content">
+      <metal:override define-slot="content">
+        foo
+      </metal:override>
+    </metal:block>
+
+  </tal:block>
+</metal:page>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/075.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/075.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/075.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a ENTITIES #IMPLIED>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/076-nested-macro-override.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/076-nested-macro-override.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/076-nested-macro-override.pt
@@ -0,0 +1,3 @@
+<metal:page use-macro="load('075-nested-macros.pt').macros['master']">
+  <metal:block fill-slot="content">bar</metal:block>
+</metal:page>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/076.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/076.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/076.xml
@@ -0,0 +1,7 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a NOTATION (n1|n2) #IMPLIED>
+<!NOTATION n1 SYSTEM "http://www.w3.org/">
+<!NOTATION n2 SYSTEM "http://www.w3.org/">
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/077-i18n-attributes.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/077-i18n-attributes.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/077-i18n-attributes.pt
@@ -0,0 +1,1 @@
+<input type="hidden" id="uploadify_label_file_title" i18n:domain="test" i18n:attributes="value Title" />
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/077.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/077.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/077.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a (1|2) #IMPLIED>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/078-tags-and-newlines.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/078-tags-and-newlines.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/078-tags-and-newlines.pt
@@ -0,0 +1,23 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+      tal:omit-tag=""
+      tal:define="id 'foo'">
+  <body>
+      <span id="toDataContainer"
+            tal:attributes="id string:${id}-toDataContainer">
+        <script type="text/javascript" tal:content="string:
+          copyDataForSubmit('${id}');">
+          // initial copying of field "field.to" --> "field"
+          copyDataForSubmit("<i tal:replace="${id}"/>");
+        </script>
+      </span>
+      <tal:block
+    repeat="value python: (1, 2, 3)"
+    ><span class="selected-option"
+           tal:content="value"
+    /><tal:block condition="not:repeat.value.end">, </tal:block
+  ></tal:block
+>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/078.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/078.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/078.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a CDATA #REQUIRED>
+]>
+<doc a="v"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/079-implicit-i18n.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/079-implicit-i18n.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/079-implicit-i18n.pt
@@ -0,0 +1,16 @@
+<html tal:define="request dict(site_url='http://host')">
+  <head>
+    <title>Welcome</title>
+  </head>
+  <body>
+    <h1>Welcome</h1>
+    <span>An edge case: ${.</span>
+    <img tal:define="site_url request.site_url" alt="Site logo" href="${site_url}/logo.png" />
+    <img alt="Site logo" href="${request.site_url}/logo.png" />
+    <div id="content">
+      foo.
+      <br />
+      bar.
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/079.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/079.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/079.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a CDATA #FIXED "v">
+]>
+<doc a="v"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/080-xmlns-namespace-on-tal.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/080-xmlns-namespace-on-tal.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/080-xmlns-namespace-on-tal.pt
@@ -0,0 +1,6 @@
+<tal:component xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+      xmlns:metal="http://xml.zope.org/namespaces/metal"
+      xmlns:tal="http://xml.zope.org/namespaces/tal">
+   Hello world
+</tal:component>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/080.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/080.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/080.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a CDATA #FIXED "v">
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/081-load-spec.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/081-load-spec.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/081-load-spec.pt
@@ -0,0 +1,1 @@
+<html metal:use-macro="load: chameleon:tests/inputs/hello_world.pt" />
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/081.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/081.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/081.xml
@@ -0,0 +1,7 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (a, b, c)>
+<!ELEMENT a (a?)>
+<!ELEMENT b (b*)>
+<!ELEMENT c (a | b)+>
+]>
+<doc><a/><b/><c><a/></c></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/082-load-spec-computed.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/082-load-spec-computed.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/082-load-spec-computed.pt
@@ -0,0 +1,1 @@
+<html tal:define="name 'hello_world'" metal:use-macro="load: chameleon:tests/inputs/${name}.pt" />
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/082.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/082.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/082.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ENTITY % e SYSTEM "e.dtd">
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/083-template-dict-to-macro.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/083-template-dict-to-macro.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/083-template-dict-to-macro.pt
@@ -0,0 +1,2 @@
+<html tal:define="template load: 032-master-template.pt"
+      metal:use-macro="template['main']" />
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/083.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/083.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/083.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ENTITY % e PUBLIC 'whatever' "e.dtd">
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/084-interpolation-in-cdata.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/084-interpolation-in-cdata.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/084-interpolation-in-cdata.pt
@@ -0,0 +1,9 @@
+<html>
+  <head>
+    <script>
+      <![CDATA[
+      alert("${'Hello world!'}");
+      ]]>
+    </script>
+  </head>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/084.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/084.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/084.xml
@@ -0,0 +1,1 @@
+<!DOCTYPE doc [<!ELEMENT doc (#PCDATA)>]><doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/085-nested-translation.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/085-nested-translation.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/085-nested-translation.pt
@@ -0,0 +1,11 @@
+<html tal:define="request dict(site_url='http://host')" i18n:domain="new">
+  <head>
+    <title>Welcome</title>
+  </head>
+  <body>
+    <h1>Welcome</h1>
+    <p i18n:translate="">
+      <a i18n:name="click_here" i18n:translate="" href="${request.site_url}">Click here</a> to continue.
+    </p>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/085.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/085.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/085.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY % e "<foo>">
+<!ENTITY e "">
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/086-self-closing.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/086-self-closing.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/086-self-closing.pt
@@ -0,0 +1,10 @@
+<html metal:use-macro="load('032-master-template.pt').macros['main']">
+  <body>
+    <div metal:fill-slot="content">
+      <div tal:condition="True">
+        <a href="#">Chart</a>
+        <div id="chart-info"/>
+      </div>
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/086.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/086.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/086.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY e "">
+<!ENTITY e "<foo>">
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/087-code-blocks.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/087-code-blocks.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/087-code-blocks.pt
@@ -0,0 +1,28 @@
+<?python
+    foo = [1, 2, 3] ?>
+
+<ul>
+  <li tal:repeat="f foo" tal:content="f" />
+</ul>
+
+<?python
+    foo = [1, 2, 3]
+    boo = [4, 5, 6]
+?>
+
+<ul>
+  <li tal:repeat="(f, g) zip(foo, boo)" tal:content="f + g" />
+</ul>
+
+<div>
+  <?python numbers = map(str, range(1, 10)) ?>
+  Please input a number from the range ${", ".join(numbers)}.
+</div>
+
+<div>
+  <?python
+     def function(i):
+         return i + 1
+     ?>
+  41 + 1 = ${function(41)}.
+</div>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/087.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/087.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/087.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ENTITY e "<foo/>">
+<!ELEMENT doc (foo)>
+<!ELEMENT foo EMPTY>
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/088-python-newlines.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/088-python-newlines.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/088-python-newlines.pt
@@ -0,0 +1,2 @@
+<span tal:replace="python: ', '.join((
+    'a', 'b', 'c'))" />
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/088.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/088.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/088.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY e "<foo>">
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/089.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/089.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/089.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ENTITY e "&#x10000;&#x10FFFD;&#x10FFFF;">
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/090.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/090.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/090.xml
@@ -0,0 +1,7 @@
+<!DOCTYPE doc [
+<!ATTLIST e a NOTATION (n) #IMPLIED>
+<!ELEMENT doc (e)*>
+<!ELEMENT e (#PCDATA)>
+<!NOTATION n PUBLIC "whatever">
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/091.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/091.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/091.xml
@@ -0,0 +1,7 @@
+<!DOCTYPE doc [
+<!NOTATION n SYSTEM "http://www.w3.org/">
+<!ENTITY e SYSTEM "http://www.w3.org/" NDATA n>
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a ENTITY "e">
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/092.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/092.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/092.xml
@@ -0,0 +1,10 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (a)*>
+<!ELEMENT a EMPTY>
+]>
+<doc>
+<a/>
+    <a/>	<a/>
+
+
+</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/093.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/093.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/093.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc>
+

</doc>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/094.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/094.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/094.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ENTITY % e "foo">
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a1 CDATA "%e;">
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/095.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/095.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/095.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ATTLIST doc a1 CDATA #IMPLIED>
+<!ATTLIST doc a1 NMTOKENS #IMPLIED>
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc a1="1  2"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/096.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/096.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/096.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ATTLIST doc a1 NMTOKENS " 1  	2 	">
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/097.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/097.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/097.xml
@@ -0,0 +1,8 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY % e SYSTEM "097.ent">
+<!ATTLIST doc a1 CDATA "v1">
+%e;
+<!ATTLIST doc a2 CDATA "v2">
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/098.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/098.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/098.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><?pi x
+y?></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/099.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/099.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/099.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/100.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/100.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/100.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ENTITY e PUBLIC ";!*#@$_%" "100.xml">
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/101-unclosed-tags.html b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/101-unclosed-tags.html
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/101-unclosed-tags.html
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    <h1><br><br>Hello world</h1>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/101.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/101.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/101.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY e """>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/102-unquoted-attributes.html b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/102-unquoted-attributes.html
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/102-unquoted-attributes.html
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    <h1 class=title align=center>Hello world</h1>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/102.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/102.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/102.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a CDATA #IMPLIED>
+]>
+<doc a="""></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/103-simple-attribute.html b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/103-simple-attribute.html
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/103-simple-attribute.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <select name="foo2" multiple style="visibility: hidden">
+      <option value="1">this should</option>
+      <option value="2">remain hidden right?</option>
+    </select>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/103.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/103.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/103.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/104.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/104.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/104.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a CDATA #IMPLIED>
+]>
+<doc a="x	y"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/105.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/105.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/105.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a CDATA #IMPLIED>
+]>
+<doc a="x	y"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/106.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/106.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/106.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a CDATA #IMPLIED>
+]>
+<doc a="x
y"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/107.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/107.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/107.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a CDATA #IMPLIED>
+]>
+<doc a="x
y"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/108.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/108.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/108.xml
@@ -0,0 +1,7 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY e "
+">
+<!ATTLIST doc a CDATA #IMPLIED>
+]>
+<doc a="x&e;y"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/109.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/109.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/109.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a CDATA #IMPLIED>
+]>
+<doc a=""></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/110.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/110.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/110.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY e "
">
+<!ATTLIST doc a CDATA #IMPLIED>
+]>
+<doc a="x&e;y"></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/111.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/111.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/111.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST doc a NMTOKENS #IMPLIED>
+]>
+<doc a=" x  y "></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/112.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/112.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/112.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (a | b)>
+<!ELEMENT a (#PCDATA)>
+]>
+<doc><a></a></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/113.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/113.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/113.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ATTLIST e a CDATA #IMPLIED>
+]>
+<doc></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/114.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/114.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/114.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY e "<![CDATA[&foo;]]>">
+]>
+<doc>&e;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/115.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/115.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/115.xml
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY e1 "&e2;">
+<!ENTITY e2 "v">
+]>
+<doc>&e1;</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/116.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/116.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/116.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+]>
+<doc><![CDATA[
+]]></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/117.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/117.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/117.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY rsqb "]">
+]>
+<doc>]</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/118.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/118.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/118.xml
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY rsqb "]]">
+]>
+<doc>]</doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/119.xml b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/119.xml
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/119.xml
@@ -0,0 +1,4 @@
+<!DOCTYPE doc [
+<!ELEMENT doc ANY>
+]>
+<doc><!-- -á --></doc>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/greeting.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/greeting.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/greeting.pt
@@ -0,0 +1,1 @@
+<div>Hello, ${name | 'undefined'}.</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/hello_world.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/hello_world.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/hello_world.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    ${'Hello world!'}
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/hello_world.txt b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/hello_world.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/inputs/hello_world.txt
@@ -0,0 +1,1 @@
+${'Hello world!'}
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.html b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.html
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.html
@@ -0,0 +1,7 @@
+<html>
+  <body>
+    Hello world!
+    Hello world!
+  </body>
+  Goodbye world!
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    Hello world!
+  </body>
+
+
+    ok
+
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.txt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/001.txt
@@ -0,0 +1,1 @@
+<Hello world><&>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/002.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/002.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/002.pt
@@ -0,0 +1,13 @@
+<html>
+  <body>
+    <div>
+      <span>Hello!</span>
+      <span>Hello.</span>
+    </div>
+    <div>
+      <span>Goodbye!</span>
+      <span>Goodbye.</span>
+    </div>
+    ok
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/003.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/003.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/003.pt
@@ -0,0 +1,17 @@
+<html>
+  <body>
+    <div>Hello world!</div>
+    <div>Hello world!</div>1
+   2<div>Hello world!</div>
+    <div>Hello world!</div>3
+    <div>Hello world!</div>5
+   6<div>Hello world!</div>
+    <div>1</div>
+    <div>1.0</div>
+    <div>True</div>
+    <div>False</div>
+    <div>0</div>
+    <div></div>
+    <div>Hello world!</div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/004.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/004.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/004.pt
@@ -0,0 +1,18 @@
+<html>
+  <body>
+    <span class="hello" />
+    <span class="hello" />
+    <span class="hello" />
+    <span />
+    <span b="2" c="3" />
+    <span a="1" c="3" />
+    <span a="1" b="2" />
+    <span a="1" />
+    <span a="1" b=";" c="3" />
+    <span a="1" b="&" c="3" />
+    <span class="goodbye" />
+    <span class=""goodbye"" />
+    <span class="'goodbye'" />
+    <span class=''goodbye'' />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/005.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/005.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/005.pt
@@ -0,0 +1,12 @@
+<html>
+  <body>
+    <img class="default" />
+    <img />
+    <span>Default</span>
+    <span>True</span>
+    <span>False</span>
+    <span>
+      <em>Computed default</em>
+    </span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/006.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/006.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/006.pt
@@ -0,0 +1,9 @@
+<html>
+  <body class="ltr">
+    <img src="#" alt="copyright (c) 2010" />
+    <img src="#" alt="copyright (c) 2010" />
+    <img src="#" alt="copyright (c) 2010" />
+    <img alt="$ignored" />
+    <img src="" alt="<type 'str'>" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/007.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/007.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/007.pt
@@ -0,0 +1,14 @@
+<html>
+  <body>
+    Hello world!
+    <div>Hello world!</div>
+    <div>Hello world!</div>
+    <type 'str'>
+    &&
+
+    Hello world
+    $leftalone
+    <div></div>
+    <div>Hello world</div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/008.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/008.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/008.pt
@@ -0,0 +1,11 @@
+<html>
+  <body>
+
+    <div class="dynamic">
+      static
+    </div>
+    <div>
+      nothing
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/009.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/009.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/009.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    <div>Hello world!</div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/010.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/010.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/010.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    <div>1 < 2</div>
+    <div>2 < 3, 2&3, 2<3, 2>3</div>
+    <div>3 < 4</div>
+    <div>4 < 5</div>
+    <div>Hello world!</div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/011-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/011-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/011-en.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    <div>Message ('message' translation into 'en')</div>
+    <div>Message ('message' translation into 'en')</div>
+    <div>Message ('message' translation into 'en')</div>
+    <div>Message ('message' translation into 'en')</div>
+    Message ('message' translation into 'en')
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/011.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/011.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/011.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    <div>Message</div>
+    <div>Message</div>
+    <div>Message</div>
+    <div>Message</div>
+    Message
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/012-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/012-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/012-en.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    <div>Hello world! ('Hello world!' translation into 'en')</div>
+    <div>Hello world! ('hello_world' translation into 'en')</div>
+    <div><sup>Hello world!</sup> ('<sup>Hello world!</sup>' translation into 'en')</div>
+    <div>Hello <em>world</em>! Goodbye <em>planet</em>! ('Hello ${first}! Goodbye ${second}!' translation into 'en')</div>
+    <div>Hello <em>world</em>! Goodbye <em>planet</em>! ('hello_goodbye' translation into 'en')</div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/012.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/012.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/012.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    <div>Hello world!</div>
+    <div>Hello world!</div>
+    <div><sup>Hello world!</sup></div>
+    <div>Hello <em>world</em>! Goodbye <em>planet</em>!</div>
+    <div>Hello <em>world</em>! Goodbye <em>planet</em>!</div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/013.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/013.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/013.pt
@@ -0,0 +1,22 @@
+<html>
+  <body>
+    <table>
+      <tr>
+        <td>
+          [1,1]
+        </td>
+        <td>
+          [1,2]
+        </td>
+      </tr>
+      <tr>
+        <td>
+          [2,1]
+        </td>
+        <td>
+          [2,2]
+        </td>
+      </tr>
+    </table>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/014.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/014.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/014.pt
@@ -0,0 +1,12 @@
+<html>
+  <body>
+    <span>
+      <span>[3,3]</span>
+      <span>[3,4]</span>
+    </span>
+    <span>
+      <span>[4,3]</span>
+      <span>[4,4]</span>
+    </span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/015-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/015-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/015-en.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    <div>Price: <span>Per kilo <em>12.5</em> ('Per kilo ${amount}' translation into 'en')</span> ('Price: ${price}' translation into 'en')</div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/015.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/015.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/015.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    <div>Price: <span>Per kilo <em>12.5</em></span></div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/016-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/016-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/016-en.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    <div>Hello world! ('Hello world!' translation into 'en')</div>
+    <img alt="Hello world! ('Hello world!' translation into 'en')" />
+    <img alt="Hello world! ('hello_world' translation into 'en')" />
+    <img alt="Hello world! ('Hello world!' translation into 'en')" />
+    <img alt="Hello world! ('hello_world' translation into 'en')" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/016.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/016.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/016.pt
@@ -0,0 +1,9 @@
+<html>
+  <body>
+    <div>Hello world!</div>
+    <img alt="Hello world!" />
+    <img alt="Hello world!" />
+    <img alt="Hello world!" />
+    <img alt="Hello world!" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/017.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/017.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/017.pt
@@ -0,0 +1,12 @@
+<html>
+  <body>
+    Hello world!
+    1
+      Hello world!
+   23
+   4Hello world!
+    <div>Hello world!</div>
+    Hello world!
+    Hello world!
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/018-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/018-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/018-en.pt
@@ -0,0 +1,3 @@
+<div xmlns="http://www.w3.org/1999/xhtml">
+  october ('october' translation into 'en') 1982 ('1982' translation into 'en') ('${monthname} ${year}' translation into 'en')
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/018.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/018.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/018.pt
@@ -0,0 +1,3 @@
+<div xmlns="http://www.w3.org/1999/xhtml">
+  october 1982
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/019.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/019.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/019.pt
@@ -0,0 +1,13 @@
+<html>
+  <body>
+    Hello world!
+    Hello world!1
+   2Hello world!
+    Hello world!3
+    Hello world!5
+   6Hello world!
+    1
+    1.0
+    True
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/020.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/020.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/020.pt
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <div id="test"></div>
+    <div>NameError thrown at 5:24.</div>
+    <div></div>
+    <div></div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/021-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/021-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/021-en.pt
@@ -0,0 +1,12 @@
+<html>
+  <body>
+    <div>Hello world! ('Hello world!' translation into 'en' with domain 'new')</div>
+    <div>Hello world! ('Hello world!' translation into 'en' with domain 'old')</div>
+    <div class="test ('test' translation into 'en' with domain 'new')">
+      Hello world!
+    </div>
+    <div class="test ('test_msgid' translation into 'en' with domain 'new')">
+      Hello world!
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/021.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/021.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/021.pt
@@ -0,0 +1,12 @@
+<html>
+  <body>
+    <div>Hello world!</div>
+    <div>Hello world!</div>
+    <div class="test">
+      Hello world!
+    </div>
+    <div class="test">
+      Hello world!
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/022.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/022.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/022.pt
@@ -0,0 +1,13 @@
+<html>
+  <body>
+    <div>
+
+      <span>ok</span>
+      <span>ok</span>
+    </div>
+    <div>
+
+      <span>ok</span>
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/023.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/023.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/023.pt
@@ -0,0 +1,6 @@
+<html>
+  <body>
+
+    <span>ok</span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/024.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/024.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/024.pt
@@ -0,0 +1,14 @@
+<html>
+  <body>
+
+
+        first
+
+      second
+
+
+      ok
+
+
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/025.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/025.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/025.pt
@@ -0,0 +1,23 @@
+<html>
+  <body>
+    <ul>
+      <li>1</li>
+      <li>2</li>
+      <li>3</li>
+      <li>1</li>
+      <li>2</li>
+      <li>3</li>
+
+
+          1,
+
+
+          2,
+
+
+          3
+
+      .
+    </ul>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/026.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/026.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/026.pt
@@ -0,0 +1,17 @@
+<div xmlns="http://www.w3.org/1999/xhtml">
+  <ul>
+    <li name="0-0" class="even">0</li>
+    <li name="1-1" class="odd">1</li>
+    <li name="2-2" class="even">2</li>
+  </ul>
+  <ul>
+    <li class="even">0</li>
+    <li class="odd">1</li>
+    <li class="even">2</li>
+  </ul>
+  <ul>
+    <li>even</li>
+    <li>odd</li>
+    <li>even</li>
+  </ul>
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/027.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/027.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/027.pt
@@ -0,0 +1,7 @@
+<div xmlns="http://www.w3.org/1999/xhtml">
+  <span id="test"
+        class="defabcdummy"
+        onClick="alert();" style="hij">abcghi</span>
+  Hello World!
+  Hello World!
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/028.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/028.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/028.pt
@@ -0,0 +1,5 @@
+<div xmlns="http://www.w3.org/1999/xhtml">
+  <option selected="True"></option>
+  <option></option>
+  <option></option>
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/029.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/029.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/029.pt
@@ -0,0 +1,3 @@
+<div xmlns="http://www.w3.org/1999/xhtml">
+  <a rel="self" href="http://python.org" id="link-id" />
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/030.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/030.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/030.pt
@@ -0,0 +1,10 @@
+<html>
+  <body>
+    <div>
+      1, 1, 2
+    </div>
+    <div>
+      2, 3, 4
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/031.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/031.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/031.pt
@@ -0,0 +1,9 @@
+<div>
+  Hello World!
+  Hello World!
+  Hello World!
+  0
+  1
+  2
+  True
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/032.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/032.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/032.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/033.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/033.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/033.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/034.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/034.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/034.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/035.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/035.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/035.pt
@@ -0,0 +1,17 @@
+<html>
+  <head>
+    <title>
+    New title
+  </title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/036.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/036.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/036.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>New title</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/037.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/037.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/037.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+    <span>ok</span>
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/038.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/038.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/038.pt
@@ -0,0 +1,6 @@
+
+<html>
+  <body>
+    <span>ok</span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/039.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/039.pt
new file mode 100644
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/040.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/040.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/040.pt
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      template-macros="master"
+      macros="master">
+
+      foo
+
+      <span template-macros="master"
+            macros="master">
+         <!-- demonstrate difference between
+              `template` and `macros` symbol -->
+      </span>
+
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/041.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/041.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/041.pt
@@ -0,0 +1,7 @@
+<html>
+  <body>
+    <div>Hello <span>world!</span></div>
+    <div>Hello <span>world!</span></div>
+    <div>Goodbye</div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/042.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/042.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/042.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+      New footer
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/043.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/043.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/043.pt
@@ -0,0 +1,11 @@
+<html>
+  <body>
+
+
+
+
+        My title
+
+
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/044.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/044.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/044.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    a, b
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/045.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/045.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/045.pt
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE application [
+  <!ENTITY nbsp "\ ">
+]>
+<application xmlns="http://research.sun.com/wadl/2006/10"
+             xsi:schemaLocation="http://research.sun.com/wadl/2006/10/wadl.xsd"
+             xmlns:wadl="http://research.sun.com/wadl/2006/10"
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <resources>
+    <resource path="/">ZZZ YYY XXX</resource>
+  </resources>
+</application>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/046.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/046.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/046.pt
@@ -0,0 +1,17 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    <span>New</span> footer
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/047.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/047.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/047.pt
@@ -0,0 +1,17 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    <em>Extended</em> footer
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/048.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/048.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/048.pt
@@ -0,0 +1,17 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    Extended footer
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/049.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/049.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/049.pt
@@ -0,0 +1,11 @@
+<html>
+  <body>
+    <pre>amp=&amp; lt=&lt;</pre>
+    <pre>amp=& lt=<</pre>
+    <script />
+    <script />
+    <script />
+    <script />
+    <img alt="1 < 2: True" />
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/050.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/050.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/050.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+     Default content
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/051.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/051.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/051.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+     Default content
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/052.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/052.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/052.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+    <span>Translated content</span>
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/053.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/053.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/053.pt
@@ -0,0 +1,6 @@
+<html>
+  <body>
+    <a href="@@view">test</a>
+    <a href="@@view">test</a>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/054.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/054.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/054.pt
@@ -0,0 +1,3 @@
+<div>
+  1984-12-31T00:00:00
+</div>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/055.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/055.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/055.pt
@@ -0,0 +1,4 @@
+<div>
+  bar
+  baz
+</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/056.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/056.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/056.pt
@@ -0,0 +1,7 @@
+<html>
+  <body>
+
+      Namespace tag
+
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/057.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/057.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/057.pt
@@ -0,0 +1,8 @@
+<html>
+  <body>
+
+    1
+    2
+    3
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/058.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/058.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/058.pt
@@ -0,0 +1,16 @@
+<html>
+  <head>
+    <script>
+      deform.addCallback(
+        '1',
+        function (oid) {
+            $('#' + oid).autocomplete({source: values});
+            $('#' + oid).autocomplete("option", options);
+        }
+      );
+    </script>
+  </head>
+  <body>
+    <!-- Form -->
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/059.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/059.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/059.pt
@@ -0,0 +1,6 @@
+<html>
+  <body>
+    <span onclick="alert(true && false);">test</span>
+    <span onclick="alert(true && false);">test</span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/060.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/060.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/060.pt
@@ -0,0 +1,8 @@
+<html>
+  <head>
+    <title>Untitled</title>
+  </head>
+  <body>
+    <h1>Untitled</h1>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/061.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/061.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/061.pt
@@ -0,0 +1,8 @@
+<html>
+  <head>
+    <title>My document</title>
+  </head>
+  <body>
+    <h1>My document</h1>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/062.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/062.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/062.pt
@@ -0,0 +1,27 @@
+<div>
+
+</div>
+
+<div>
+  <!-- ${left alone} -->
+</div>
+
+<div>
+  <!-- not left alone -->
+</div>
+
+<div>
+  <!-- not left alone -->
+</div>
+
+<div>
+  <!-- ${left alone} -->
+</div>
+
+<!--[if IE 6]>
+  Special instructions for IE 6 here
+<![endif]-->
+
+<!--[if IE 6]>
+  ${left alone}
+<![endif]-->
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/063.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/063.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/063.pt
@@ -0,0 +1,3 @@
+<div>
+  2
+</div>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/064.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/064.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/064.pt
@@ -0,0 +1,3 @@
+
+  <div	id="test"	class="test">
+  </div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/065.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/065.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/065.pt
@@ -0,0 +1,13 @@
+<html>
+  <head>
+    <title>Title</title>
+  </head>
+  <body>
+    <div id="content">
+      <div>Content</div>
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/066.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/066.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/066.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    Hello world!
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/067.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/067.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/067.pt
@@ -0,0 +1,6 @@
+<html>
+  <body>
+    <img src="#" class="up" />
+    <img src="#" class="down" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/068.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/068.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/068.pt
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <span>0 < 1 or 0 > 1</span>
+    <span>0 < 1 or 0 > 1</span>
+    <span class="0 < 1 or 0 > 1" />
+    <span>0 < 1 or 0 > 1</span>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/069-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/069-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/069-en.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Title ('title' translation into 'en' with domain 'test')</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/069.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/069.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/069.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Title</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/070-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/070-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/070-en.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Title ('title' translation into 'en' with domain 'test')</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/070.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/070.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/070.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Title</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/071.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/071.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/071.pt
@@ -0,0 +1,11 @@
+<html>
+  <body>
+    <input type="input" checked="True" />
+    <input type="input" />
+    <input type="input" />
+    <input type="input" checked="checked" />
+    <input type="input" checked />
+    <input type="input" />
+    <input type="input" class="True" />
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/072.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/072.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/072.pt
@@ -0,0 +1,19 @@
+<html>
+  <body>
+    <ul>
+      <li class="odd">1</li>
+      <li>2</li>
+      <li class="odd">3</li>
+    </ul>
+    <ul>
+      <li class="odd">1</li>
+      <li>2</li>
+      <li class="odd">3</li>
+    </ul>
+    <ul>
+      <li class="odd">1</li>
+      <li>2</li>
+      <li class="odd">3</li>
+    </ul>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/073.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/073.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/073.pt
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title>my title — my site</title></head>
+<body></body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/074.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/074.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/074.pt
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="windows-1251" ?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title>my title — my site</title></head>
+<body></body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/075.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/075.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/075.pt
@@ -0,0 +1,19 @@
+
+  <html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+
+        foo
+
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
+
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/076.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/076.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/076.pt
@@ -0,0 +1,17 @@
+
+  <html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+<BLANKLINE>
+      bar
+<BLANKLINE>
+    </div>
+    <div id="footer">
+<BLANKLINE>
+    </div>
+  </body>
+</html>
+
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/077-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/077-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/077-en.pt
@@ -0,0 +1,1 @@
+<input type="hidden" id="uploadify_label_file_title" value="value ('Title' translation into 'en' with domain 'test')" />
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/077.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/077.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/077.pt
@@ -0,0 +1,1 @@
+<input type="hidden" id="uploadify_label_file_title" value="value" />
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/078.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/078.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/078.pt
@@ -0,0 +1,11 @@
+
+  <body>
+      <span id="foo-toDataContainer">
+        <script type="text/javascript">
+          copyDataForSubmit('foo');</script>
+      </span>
+      <span class="selected-option">1</span>, 
+      <span class="selected-option">2</span>, 
+      <span class="selected-option">3</span>
+  </body>
+
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/079-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/079-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/079-en.pt
@@ -0,0 +1,16 @@
+<html>
+  <head>
+    <title>Welcome ('Welcome' translation into 'en')</title>
+  </head>
+  <body>
+    <h1>Welcome ('Welcome' translation into 'en')</h1>
+    <span>An edge case: ${. ('An edge case: ${.' translation into 'en')</span>
+    <img alt="Site logo ('Site logo' translation into 'en')" href="http://host/logo.png" />
+    <img alt="Site logo ('Site logo' translation into 'en')" href="http://host/logo.png" />
+    <div id="content">
+      foo. ('foo.' translation into 'en')
+      <br />
+      bar. ('bar.' translation into 'en')
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/079.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/079.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/079.pt
@@ -0,0 +1,16 @@
+<html>
+  <head>
+    <title>Welcome</title>
+  </head>
+  <body>
+    <h1>Welcome</h1>
+    <span>An edge case: ${.</span>
+    <img alt="Site logo" href="http://host/logo.png" />
+    <img alt="Site logo" href="http://host/logo.png" />
+    <div id="content">
+      foo.
+      <br />
+      bar.
+    </div>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/080.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/080.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/080.pt
@@ -0,0 +1,3 @@
+
+   Hello world
+
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/081.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/081.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/081.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    Hello world!
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/082.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/082.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/082.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    Hello world!
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/083.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/083.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/083.pt
@@ -0,0 +1,15 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+
+        <!-- content here -->
+
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/084.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/084.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/084.pt
@@ -0,0 +1,9 @@
+<html>
+  <head>
+    <script>
+      <![CDATA[
+      alert("Hello world!");
+      ]]>
+    </script>
+  </head>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/085-en.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/085-en.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/085-en.pt
@@ -0,0 +1,9 @@
+<html>
+  <head>
+    <title>Welcome</title>
+  </head>
+  <body>
+    <h1>Welcome</h1>
+    <p><a href="http://host">Click here ('Click here' translation into 'en' with domain 'new')</a> to continue. ('${click_here} to continue.' translation into 'en' with domain 'new')</p>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/085.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/085.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/085.pt
@@ -0,0 +1,9 @@
+<html>
+  <head>
+    <title>Welcome</title>
+  </head>
+  <body>
+    <h1>Welcome</h1>
+    <p><a href="http://host">Click here</a> to continue.</p>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/086.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/086.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/086.pt
@@ -0,0 +1,18 @@
+<html>
+  <head>
+    <title>Master template</title>
+  </head>
+  <body>
+    <div id="content">
+      <div>
+      <div>
+        <a href="#">Chart</a>
+        <div id="chart-info"/>
+      </div>
+    </div>
+    </div>
+    <div id="footer">
+
+    </div>
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/087.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/087.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/087.pt
@@ -0,0 +1,25 @@
+
+
+<ul>
+  <li>1</li>
+  <li>2</li>
+  <li>3</li>
+</ul>
+
+
+
+<ul>
+  <li>5</li>
+  <li>7</li>
+  <li>9</li>
+</ul>
+
+<div>
+
+  Please input a number from the range 1, 2, 3, 4, 5, 6, 7, 8, 9.
+</div>
+
+<div>
+
+  41 + 1 = 42.
+</div>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/088.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/088.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/088.pt
@@ -0,0 +1,1 @@
+a, b, c
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/101.html b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/101.html
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/101.html
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    <h1><br><br>Hello world</h1>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/102.html b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/102.html
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/102.html
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    <h1 class=title align=center>Hello world</h1>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/103.html b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/103.html
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/103.html
@@ -0,0 +1,8 @@
+<html>
+  <body>
+    <select name="foo2" multiple style="visibility: hidden">
+      <option value="1">this should</option>
+      <option value="2">remain hidden right?</option>
+    </select>
+  </body>
+</html>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/greeting.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/greeting.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/greeting.pt
@@ -0,0 +1,1 @@
+<div>Hello, undefined.</div>
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/hello_world.pt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/hello_world.pt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/hello_world.pt
@@ -0,0 +1,5 @@
+<html>
+  <body>
+    Hello world!
+  </body>
+</html>
\ No newline at end of file
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/hello_world.txt b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/hello_world.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/outputs/hello_world.txt
@@ -0,0 +1,1 @@
+Hello world!
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/test_doctests.py b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_doctests.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_doctests.py
@@ -0,0 +1,40 @@
+import unittest
+import doctest
+
+OPTIONFLAGS = (doctest.ELLIPSIS |
+               doctest.REPORT_ONLY_FIRST_FAILURE)
+
+
+class DoctestCase(unittest.TestCase):
+    def __new__(self, test):
+        return getattr(self, test)()
+
+    @classmethod
+    def test_tal(cls):
+        from chameleon import tal
+        return doctest.DocTestSuite(
+            tal, optionflags=OPTIONFLAGS)
+
+    @classmethod
+    def test_tales(cls):
+        from chameleon import tales
+        return doctest.DocTestSuite(
+            tales, optionflags=OPTIONFLAGS)
+
+    @classmethod
+    def test_utils(cls):
+        from chameleon import utils
+        return doctest.DocTestSuite(
+            utils, optionflags=OPTIONFLAGS)
+
+    @classmethod
+    def test_exc(cls):
+        from chameleon import exc
+        return doctest.DocTestSuite(
+            exc, optionflags=OPTIONFLAGS)
+
+    @classmethod
+    def test_compiler(cls):
+        from chameleon import compiler
+        return doctest.DocTestSuite(
+            compiler, optionflags=OPTIONFLAGS)
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/test_loader.py b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_loader.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_loader.py
@@ -0,0 +1,79 @@
+import unittest
+
+
+class LoadTests:
+    def _makeOne(self, search_path=None, **kwargs):
+        klass = self._getTargetClass()
+        return klass(search_path, **kwargs)
+
+    def _getTargetClass(self):
+        from chameleon.loader import TemplateLoader
+        return TemplateLoader
+
+    def test_load_relative(self):
+        import os
+        here = os.path.join(os.path.dirname(__file__), "inputs")
+        loader = self._makeOne(search_path=[here])
+        result = self._load(loader, 'hello_world.pt')
+        self.assertEqual(result.filename, os.path.join(here, 'hello_world.pt'))
+
+    def test_consecutive_loads(self):
+        import os
+        here = os.path.join(os.path.dirname(__file__), "inputs")
+        loader = self._makeOne(search_path=[here])
+
+        self.assertTrue(
+            self._load(loader, 'hello_world.pt') is \
+            self._load(loader, 'hello_world.pt'))
+
+    def test_load_relative_badpath_in_searchpath(self):
+        import os
+        here = os.path.join(os.path.dirname(__file__), "inputs")
+        loader = self._makeOne(search_path=[os.path.join(here, 'none'), here])
+        result = self._load(loader, 'hello_world.pt')
+        self.assertEqual(result.filename, os.path.join(here, 'hello_world.pt'))
+
+    def test_load_abs(self):
+        import os
+        here = os.path.join(os.path.dirname(__file__), "inputs")
+        loader = self._makeOne()
+        abs = os.path.join(here, 'hello_world.pt')
+        result = self._load(loader, abs)
+        self.assertEqual(result.filename, abs)
+
+
+class LoadPageTests(unittest.TestCase, LoadTests):
+    def _load(self, loader, filename):
+        from chameleon.zpt import template
+        return loader.load(filename, template.PageTemplateFile)
+
+
+class ZPTLoadTests(unittest.TestCase):
+    def _makeOne(self, *args, **kwargs):
+        import os
+        here = os.path.join(os.path.dirname(__file__), "inputs")
+        from chameleon.zpt import loader
+        return loader.TemplateLoader(here, **kwargs)
+
+    def test_load_xml(self):
+        loader = self._makeOne()
+        template = loader.load("hello_world.pt", "xml")
+        from chameleon.zpt.template import PageTemplateFile
+        self.assertTrue(isinstance(template, PageTemplateFile))
+
+    def test_load_text(self):
+        loader = self._makeOne()
+        template = loader.load("hello_world.txt", "text")
+        from chameleon.zpt.template import PageTextTemplateFile
+        self.assertTrue(isinstance(template, PageTextTemplateFile))
+
+    def test_load_getitem_gets_xml_file(self):
+        loader = self._makeOne()
+        template = loader["hello_world.pt"]
+        from chameleon.zpt.template import PageTemplateFile
+        self.assertTrue(isinstance(template, PageTemplateFile))
+
+
+def test_suite():
+    import sys
+    return unittest.findTestCases(sys.modules[__name__])
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/test_parser.py b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_parser.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_parser.py
@@ -0,0 +1,92 @@
+from __future__ import with_statement
+
+import sys
+
+from unittest import TestCase
+
+from ..namespaces import XML_NS
+from ..namespaces import XMLNS_NS
+from ..namespaces import PY_NS
+
+
+class ParserTest(TestCase):
+    def test_sample_files(self):
+        import os
+        import traceback
+        path = os.path.join(os.path.dirname(__file__), "inputs")
+        for filename in os.listdir(path):
+            if not filename.endswith('.html'):
+                continue
+
+            with open(os.path.join(path, filename), 'rb') as f:
+                source = f.read()
+
+            from ..utils import read_encoded
+            try:
+                want = read_encoded(source)
+            except UnicodeDecodeError:
+                exc = sys.exc_info()[1]
+                self.fail("%s - %s" % (exc, filename))
+
+            from ..tokenize import iter_xml
+            from ..parser import ElementParser
+            try:
+                tokens = iter_xml(want)
+                parser = ElementParser(tokens, {
+                    'xmlns': XMLNS_NS,
+                    'xml': XML_NS,
+                    'py': PY_NS,
+                    })
+                elements = tuple(parser)
+            except:
+                self.fail(traceback.format_exc())
+
+            output = []
+
+            def render(kind, args):
+                if kind == 'element':
+                    # start tag
+                    tag, end, children = args
+                    output.append("%(prefix)s%(name)s" % tag)
+
+                    for attr in tag['attrs']:
+                        output.append(
+                            "%(space)s%(name)s%(eq)s%(quote)s%(value)s%(quote)s" % \
+                            attr
+                            )
+
+                    output.append("%(suffix)s" % tag)
+
+                    # children
+                    for item in children:
+                        render(*item)
+
+                    # end tag
+                    output.append(
+                        "%(prefix)s%(name)s%(space)s%(suffix)s" % end
+                        )
+                elif kind == 'text':
+                    text = args[0]
+                    output.append(text)
+                elif kind == 'start_tag':
+                    node = args[0]
+                    output.append(
+                        "%(prefix)s%(name)s%(space)s%(suffix)s" % node
+                        )
+                else:
+                    raise RuntimeError("Not implemented: %s." % kind)
+
+            for kind, args in elements:
+                render(kind, args)
+
+            got = "".join(output)
+
+            from doctest import OutputChecker
+            checker = OutputChecker()
+
+            if checker.check_output(want, got, 0) is False:
+                from doctest import Example
+                example = Example(f.name, want)
+                diff = checker.output_difference(
+                    example, got, 0)
+                self.fail("(%s) - \n%s" % (f.name, diff))
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/test_sniffing.py b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_sniffing.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_sniffing.py
@@ -0,0 +1,124 @@
+from __future__ import with_statement
+
+import os
+import unittest
+import tempfile
+import shutil
+
+from chameleon.utils import unicode_string
+from chameleon.utils import encode_string
+
+
+class TypeSniffingTestCase(unittest.TestCase):
+    def setUp(self):
+        self.tempdir = tempfile.mkdtemp(prefix='chameleon-tests')
+
+    def tearDown(self):
+        shutil.rmtree(self.tempdir)
+
+    def _get_temporary_file(self):
+        filename = os.path.join(self.tempdir, 'template.py')
+        assert not os.path.exists(filename)
+        f = open(filename, 'w')
+        f.flush()
+        f.close()
+        return filename
+
+    def get_template(self, text):
+        fn = self._get_temporary_file()
+
+        with open(fn, 'wb') as tmpfile:
+            tmpfile.write(text)
+
+        from chameleon.template import BaseTemplateFile
+
+        class DummyTemplateFile(BaseTemplateFile):
+            def cook(self, body):
+                self.body = body
+
+        template = DummyTemplateFile(fn)
+        template.cook_check()
+        return template
+
+    def check_content_type(self, text, expected_type):
+        from chameleon.utils import read_bytes
+        content_type = read_bytes(text, 'ascii')[2]
+        self.assertEqual(content_type, expected_type)
+
+    def test_xml_encoding(self):
+        from chameleon.utils import xml_prefixes
+
+        document1 = unicode_string(
+            "<?xml version='1.0' encoding='ascii'?><doc/>"
+            )
+        document2 = unicode_string(
+            "<?xml\tversion='1.0' encoding='ascii'?><doc/>"
+            )
+
+        for bom, encoding in xml_prefixes:
+            try:
+                "".encode(encoding)
+            except LookupError:
+                # System does not support this encoding
+                continue
+
+            self.check_content_type(document1.encode(encoding), "text/xml")
+            self.check_content_type(document2.encode(encoding), "text/xml")
+
+    HTML_PUBLIC_ID = "-//W3C//DTD HTML 4.01 Transitional//EN"
+    HTML_SYSTEM_ID = "http://www.w3.org/TR/html4/loose.dtd"
+
+    # Couldn't find the code that handles this... yet.
+    # def test_sniffer_html_ascii(self):
+    #     self.check_content_type(
+    #         "<!DOCTYPE html [ SYSTEM '%s' ]><html></html>"
+    #         % self.HTML_SYSTEM_ID,
+    #         "text/html")
+    #     self.check_content_type(
+    #         "<html><head><title>sample document</title></head></html>",
+    #         "text/html")
+
+    # TODO: This reflects a case that simply isn't handled by the
+    # sniffer; there are many, but it gets it right more often than
+    # before.
+    def donttest_sniffer_xml_simple(self):
+        self.check_content_type("<doc><element/></doc>", "text/xml")
+
+    def test_html_default_encoding(self):
+        body = encode_string(
+            '<html><head><title>' \
+            '\xc3\x90\xc2\xa2\xc3\x90\xc2\xb5' \
+            '\xc3\x91\xc2\x81\xc3\x91\xc2\x82' \
+            '</title></head></html>')
+
+        template = self.get_template(body)
+        self.assertEqual(template.body, body.decode('utf-8'))
+
+    def test_html_encoding_by_meta(self):
+        body = encode_string(
+            '<html><head><title>' \
+            '\xc3\x92\xc3\xa5\xc3\xb1\xc3\xb2' \
+            '</title><meta http-equiv="Content-Type"' \
+            ' content="text/html; charset=windows-1251"/>' \
+            "</head></html>")
+
+        template = self.get_template(body)
+        self.assertEqual(template.body, body.decode('windows-1251'))
+
+    def test_xhtml(self):
+        body = encode_string(
+            '<html><head><title>' \
+            '\xc3\x92\xc3\xa5\xc3\xb1\xc3\xb2' \
+            '</title><meta http-equiv="Content-Type"' \
+            ' content="text/html; charset=windows-1251"/>' \
+            "</head></html>")
+
+        template = self.get_template(body)
+        self.assertEqual(template.body, body.decode('windows-1251'))
+
+
+def test_suite():
+    return unittest.makeSuite(TypeSniffingTestCase)
+
+if __name__ == "__main__":
+    unittest.main(defaultTest="test_suite")
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/test_templates.py b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_templates.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_templates.py
@@ -0,0 +1,679 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+
+import re
+import os
+import sys
+import shutil
+import tempfile
+
+from functools import wraps
+from functools import partial
+
+try:
+    from unittest2 import TestCase
+except ImportError:
+    from unittest import TestCase
+
+
+from chameleon.utils import byte_string
+
+
+class Message(object):
+    def __str__(self):
+        return "message"
+
+
+class ImportTestCase(TestCase):
+    def test_pagetemplates(self):
+        from chameleon import PageTemplate
+        from chameleon import PageTemplateFile
+        from chameleon import PageTemplateLoader
+
+    def test_pagetexttemplates(self):
+        from chameleon import PageTextTemplate
+        from chameleon import PageTextTemplateFile
+
+
+class TemplateFileTestCase(TestCase):
+    @property
+    def _class(self):
+        from chameleon.template import BaseTemplateFile
+
+        class TestTemplateFile(BaseTemplateFile):
+            cook_count = 0
+
+            def cook(self, body):
+                self.cook_count += 1
+                self._cooked = True
+
+        return TestTemplateFile
+
+    def setUp(self):
+        self.tempdir = tempfile.mkdtemp(prefix='chameleon-tests')
+
+    def tearDown(self):
+        shutil.rmtree(self.tempdir)
+
+    def _get_temporary_file(self):
+        filename = os.path.join(self.tempdir, 'template.py')
+        assert not os.path.exists(filename)
+        f = open(filename, 'w')
+        f.flush()
+        f.close()
+        return filename
+
+    def test_cook_check(self):
+        fn = self._get_temporary_file()
+        template = self._class(fn)
+        template.cook_check()
+        self.assertEqual(template.cook_count, 1)
+
+    def test_auto_reload(self):
+        fn = self._get_temporary_file()
+
+        # set time in past
+        os.utime(fn, (0, 0))
+
+        template = self._class(fn, auto_reload=True)
+        template.cook_check()
+
+        # a second cook check makes no difference
+        template.cook_check()
+        self.assertEqual(template.cook_count, 1)
+
+        # set current time on file
+        os.utime(fn, None)
+
+        # file is reloaded
+        template.cook_check()
+        self.assertEqual(template.cook_count, 2)
+
+    def test_relative_is_expanded_to_cwd(self):
+        template = self._class("___does_not_exist___")
+        try:
+            template.cook_check()
+        except IOError:
+            exc = sys.exc_info()[1]
+            self.assertEqual(
+                os.getcwd(),
+                os.path.dirname(exc.filename)
+                )
+        else:
+            self.fail("Expected OSError.")
+
+
+class RenderTestCase(TestCase):
+    root = os.path.dirname(__file__)
+
+    def find_files(self, ext):
+        inputs = os.path.join(self.root, "inputs")
+        outputs = os.path.join(self.root, "outputs")
+        for filename in sorted(os.listdir(inputs)):
+            name, extension = os.path.splitext(filename)
+            if extension != ext:
+                continue
+            path = os.path.join(inputs, filename)
+
+            # if there's no output file, treat document as static and
+            # expect intput equal to output
+            import glob
+            globbed = tuple(glob.iglob(os.path.join(
+                outputs, "%s*%s" % (name.split('-', 1)[0], ext))))
+
+            if not globbed:
+                self.fail("Missing output for: %s." % name)
+
+            for output in globbed:
+                name, ext = os.path.splitext(output)
+                basename = os.path.basename(name)
+                if '-' in basename:
+                    language = basename.split('-')[1]
+                else:
+                    language = None
+
+                yield path, output, language
+
+
+class ZopePageTemplatesTest(RenderTestCase):
+    @property
+    def from_string(body):
+        from ..zpt.template import PageTemplate
+        return partial(PageTemplate, keep_source=True)
+
+    @property
+    def from_file(body):
+        from ..zpt.template import PageTemplateFile
+        return partial(PageTemplateFile, keep_source=True)
+
+    def template(body):
+        def decorator(func):
+            @wraps(func)
+            def wrapper(self):
+                template = self.from_string(body)
+                return func(self, template)
+
+            return wrapper
+        return decorator
+
+    def error(body):
+        def decorator(func):
+            @wraps(func)
+            def wrapper(self):
+                from chameleon.exc import TemplateError
+                try:
+                    template = self.from_string(body)
+                except TemplateError:
+                    exc = sys.exc_info()[1]
+                    return func(self, body, exc)
+                else:
+                    self.fail("Expected exception.")
+
+            return wrapper
+        return decorator
+
+    def test_syntax_error_in_strict_mode(self):
+        from chameleon.exc import ExpressionError
+
+        self.assertRaises(
+            ExpressionError,
+            self.from_string,
+            """<tal:block replace='bad /// ' />""",
+            strict=True
+            )
+
+    def test_syntax_error_in_non_strict_mode(self):
+        from chameleon.exc import ExpressionError
+
+        body = """<tal:block replace='bad /// ' />"""
+        template = self.from_string(body, strict=False)
+
+        try:
+            template()
+        except ExpressionError:
+            exc = sys.exc_info()[1]
+            self.assertTrue(body[exc.offset:].startswith('bad ///'))
+        else:
+            self.fail("Expected exception")
+
+    @error("""<tal:dummy attributes=\"dummy 'dummy'\" />""")
+    def test_attributes_on_tal_tag_fails(self, body, exc):
+        self.assertTrue(body[exc.offset:].startswith('dummy'))
+
+    @error("""<tal:dummy i18n:attributes=\"foo, bar\" />""")
+    def test_i18n_attributes_with_non_identifiers(self, body, exc):
+        self.assertTrue(body[exc.offset:].startswith('foo,'))
+
+    @error("""<tal:dummy repeat=\"key,value mydict.items()\">""")
+    def test_repeat_syntax_error_message(self, body, exc):
+        self.assertTrue(body[exc.offset:].startswith('key,value'))
+
+    def test_encoded(self):
+        filename = '074-encoded-template.pt'
+        with open(os.path.join(self.root, 'inputs', filename), 'rb') as f:
+            body = f.read()
+
+        self.from_string(body)
+
+    def test_utf8_encoded(self):
+        filename = '073-utf8-encoded.pt'
+        with open(os.path.join(self.root, 'inputs', filename), 'rb') as f:
+            body = f.read()
+
+        self.from_string(body)
+
+    def test_unicode_decode_error(self):
+        template = self.from_file(
+            os.path.join(self.root, 'inputs', 'greeting.pt')
+            )
+
+        string = native = "the artist formerly known as ƤŗíƞĆě"
+        try:
+            string = string.decode('utf-8')
+        except AttributeError:
+            pass
+
+        class name:
+            @staticmethod
+            def __html__():
+                # This raises a decoding exception
+                string.encode('utf-8').decode('ascii')
+
+                self.fail("Expected exception raised.")
+
+        try:
+            template(name=name)
+        except UnicodeDecodeError:
+            exc = sys.exc_info()[1]
+            formatted = str(exc)
+
+            # There's a marker under the expression that has the
+            # unicode decode error
+            self.assertTrue('^^^^^' in formatted)
+            self.assertTrue(native in formatted)
+        else:
+            self.fail("expected error")
+
+    def test_custom_encoding_for_str_or_bytes_in_content(self):
+        string = '<div>Тест${text}</div>'
+        try:
+            string = string.decode('utf-8')
+        except AttributeError:
+            pass
+
+        template = self.from_string(string, encoding="windows-1251")
+
+        text = 'Тест'
+
+        try:
+            text = text.decode('utf-8')
+        except AttributeError:
+            pass
+
+        rendered = template(text=text.encode('windows-1251'))
+
+        self.assertEqual(
+            rendered,
+            string.replace('${text}', text)
+            )
+
+    def test_custom_encoding_for_str_or_bytes_in_attributes(self):
+        string = '<img tal="Тест${text}" />'
+        try:
+            string = string.decode('utf-8')
+        except AttributeError:
+            pass
+
+        template = self.from_string(string, encoding="windows-1251")
+
+        text = 'Тест'
+
+        try:
+            text = text.decode('utf-8')
+        except AttributeError:
+            pass
+
+        rendered = template(text=text.encode('windows-1251'))
+
+        self.assertEqual(
+            rendered,
+            string.replace('${text}', text)
+            )
+
+    def test_null_translate_function(self):
+        template = self.from_string('${test}', translate=None)
+        rendered = template(test=object())
+        self.assertTrue('object' in rendered)
+
+    def test_object_substitution_coerce_to_str(self):
+        template = self.from_string('${test}', translate=None)
+
+        class dummy(object):
+            def __repr__(inst):
+                self.fail("call not expected")
+
+            def __str__(inst):
+                return '<dummy>'
+
+        rendered = template(test=dummy())
+        self.assertEqual(rendered, '<dummy>')
+
+    def test_repr(self):
+        template = self.from_file(
+            os.path.join(self.root, 'inputs', 'hello_world.pt')
+            )
+        self.assertTrue(template.filename in repr(template))
+
+    def test_underscore_variable(self):
+        template = self.from_string(
+            "<div tal:define=\"_dummy 'foo'\">${_dummy}</div>"
+            )
+        self.assertTrue(template(), "<div>foo</div>")
+
+    def test_trim_attribute_space(self):
+        document = '''<div
+                  class="document"
+                  id="test"
+                  tal:attributes="class string:${default} test"
+            />'''
+
+        result1 = self.from_string(
+            document)()
+
+        result2 = self.from_string(
+            document, trim_attribute_space=True)()
+
+        self.assertEqual(result1.count(" "), 49)
+        self.assertEqual(result2.count(" "), 4)
+        self.assertTrue(" />" in result1)
+        self.assertTrue(" />" in result2)
+
+    def test_exception(self):
+        from traceback import format_exception_only
+
+        template = self.from_string(
+            "<div tal:define=\"dummy foo\">${dummy}</div>"
+            )
+        try:
+            template()
+        except:
+            exc = sys.exc_info()[1]
+            formatted = str(exc)
+            self.assertFalse('NameError:' in formatted)
+            self.assertTrue('foo' in formatted)
+            self.assertTrue('(1:23)' in formatted)
+
+            formatted_exc = "\n".join(format_exception_only(type(exc), exc))
+            self.assertTrue('NameError: foo' in formatted_exc)
+        else:
+            self.fail("expected error")
+
+    def test_create_formatted_exception(self):
+        from chameleon.utils import create_formatted_exception
+
+        exc = create_formatted_exception(NameError('foo'), NameError, str)
+        self.assertEqual(exc.args, ('foo', ))
+
+        class MyNameError(NameError):
+            def __init__(self, boo):
+                NameError.__init__(self, boo)
+                self.bar = boo
+
+        exc = create_formatted_exception(MyNameError('foo'), MyNameError, str)
+        self.assertEqual(exc.args, ('foo', ))
+        self.assertEqual(exc.bar, 'foo')
+
+    def test_create_formatted_exception_no_subclass(self):
+        from chameleon.utils import create_formatted_exception
+
+        class DifficultMetaClass(type):
+            def __init__(self, class_name, bases, namespace):
+                if not bases == (BaseException, ):
+                    raise TypeError(bases)
+
+        Difficult = DifficultMetaClass('Difficult', (BaseException, ), {'args': ()})
+
+        exc = create_formatted_exception(Difficult(), Difficult, str)
+        self.assertEqual(exc.args, ())
+
+    def test_error_handler_makes_safe_copy(self):
+        calls = []
+
+        class TestException(Exception):
+            def __init__(self, *args, **kwargs):
+                calls.append((args, kwargs))
+
+        def _render(stream, econtext, rcontext):
+            exc = TestException('foo', bar='baz')
+            rcontext['__error__'] = ('expression', 1, 42, 'test.pt', exc),
+            raise exc
+
+        template = self.from_string("")
+        template._render = _render
+        try:
+            template()
+        except TestException:
+            self.assertEqual(calls, [(('foo', ), {'bar': 'baz'})])
+            exc = sys.exc_info()[1]
+            formatted = str(exc)
+            self.assertTrue('TestException' in formatted)
+            self.assertTrue('"expression"' in formatted)
+            self.assertTrue('(1:42)' in formatted)
+        else:
+            self.fail("unexpected error")
+
+    def test_double_underscore_variable(self):
+        from chameleon.exc import TranslationError
+        self.assertRaises(
+            TranslationError, self.from_string,
+            "<div tal:define=\"__dummy 'foo'\">${__dummy}</div>",
+            )
+
+    def test_compiler_internals_are_disallowed(self):
+        from chameleon.compiler import COMPILER_INTERNALS_OR_DISALLOWED
+        from chameleon.exc import TranslationError
+
+        for name in COMPILER_INTERNALS_OR_DISALLOWED:
+            body = "<d tal:define=\"%s 'foo'\">${%s}</d>" % (name, name)
+            self.assertRaises(TranslationError, self.from_string, body)
+
+    def test_fast_translate_mapping(self):
+        template = self.from_string(
+            '<div i18n:translate="">'
+            '<span i18n:name="name">foo</span>'
+            '</div>')
+
+        self.assertEqual(template(), '<div><span>foo</span></div>')
+
+    def test_translate_is_not_an_internal(self):
+        macro = self.from_string('<span i18n:translate="">bar</span>')
+        template = self.from_string(
+            '''
+            <tal:defs define="translate string:">
+              <span i18n:translate="">foo</span>
+              <metal:macro use-macro="macro" />
+            </tal:defs>
+            ''')
+
+        result = template(macro=macro)
+        self.assertTrue('foo' in result)
+        self.assertTrue('foo' in result)
+
+    def test_literal_false(self):
+        template = self.from_string(
+            '<input type="input" tal:attributes="checked False" />'
+            '<input type="input" tal:attributes="checked True" />'
+            '<input type="input" tal:attributes="checked None" />'
+            '<input type="input" tal:attributes="checked default" />',
+            literal_false=True,
+            )
+
+        self.assertEqual(
+            template(),
+            '<input type="input" checked="False" />'
+            '<input type="input" checked="True" />'
+            '<input type="input" />'
+            '<input type="input" />',
+            template.source
+            )
+
+    def test_boolean_attributes(self):
+        template = self.from_string(
+            '<input type="input" tal:attributes="checked False" />'
+            '<input type="input" tal:attributes="checked True" />'
+            '<input type="input" tal:attributes="checked None" />'
+            '<input type="input" tal:attributes="checked \'\'" />'
+            '<input type="input" tal:attributes="checked default" />'
+            '<input type="input" checked="checked" tal:attributes="checked default" />',
+            boolean_attributes=set(['checked'])
+            )
+
+        self.assertEqual(
+            template(),
+            '<input type="input" />'
+            '<input type="input" checked="checked" />'
+            '<input type="input" />'
+            '<input type="input" />'
+            '<input type="input" />'
+            '<input type="input" checked="checked" />',
+            template.source
+            )
+
+    def test_default_debug_flag(self):
+        from chameleon.config import DEBUG_MODE
+        template = self.from_file(
+            os.path.join(self.root, 'inputs', 'hello_world.pt'),
+            )
+        self.assertEqual(template.debug, DEBUG_MODE)
+        self.assertTrue('debug' not in template.__dict__)
+
+    def test_debug_flag_on_string(self):
+        from chameleon.loader import ModuleLoader
+
+        with open(os.path.join(self.root, 'inputs', 'hello_world.pt')) as f:
+            source = f.read()
+
+        template = self.from_string(source, debug=True)
+
+        self.assertTrue(template.debug)
+        self.assertTrue(isinstance(template.loader, ModuleLoader))
+
+    def test_debug_flag_on_file(self):
+        from chameleon.loader import ModuleLoader
+        template = self.from_file(
+            os.path.join(self.root, 'inputs', 'hello_world.pt'),
+            debug=True,
+            )
+        self.assertTrue(template.debug)
+        self.assertTrue(isinstance(template.loader, ModuleLoader))
+
+    def test_tag_mismatch(self):
+        from chameleon.exc import ParseError
+
+        try:
+            self.from_string("""
+            <div metal:use-macro="layout">
+            <div metal:fill-slot="name"></dav>
+            </div>
+            """)
+        except ParseError:
+            exc = sys.exc_info()[1]
+            self.assertTrue("</dav>" in str(exc))
+        else:
+            self.fail("Expected error.")
+
+
+class ZopeTemplatesTestSuite(RenderTestCase):
+    def setUp(self):
+        self.temp_path = temp_path = tempfile.mkdtemp()
+
+        @self.addCleanup
+        def cleanup(path=temp_path):
+            shutil.rmtree(path)
+
+    def test_pt_files(self):
+        from ..zpt.template import PageTemplateFile
+
+        class Literal(object):
+            def __init__(self, s):
+                self.s = s
+
+            def __html__(self):
+                return self.s
+
+            def __str__(self):
+                raise RuntimeError(
+                    "%r is a literal." % self.s)
+
+        from chameleon.loader import TemplateLoader
+        loader = TemplateLoader(os.path.join(self.root, "inputs"))
+
+        self.execute(
+            ".pt", PageTemplateFile,
+            literal=Literal("<div>Hello world!</div>"),
+            content="<div>Hello world!</div>",
+            message=Message(),
+            load=loader.bind(PageTemplateFile),
+            )
+
+    def test_txt_files(self):
+        from ..zpt.template import PageTextTemplateFile
+        self.execute(".txt", PageTextTemplateFile)
+
+    def execute(self, ext, factory, **kwargs):
+        def translate(msgid, domain=None, mapping=None, context=None,
+                      target_language=None, default=None):
+            if default is None:
+                default = str(msgid)
+
+            if isinstance(msgid, Message):
+                default = "Message"
+
+            if mapping:
+                default = re.sub(r'\${([a-z_]+)}', r'%(\1)s', default) % \
+                          mapping
+
+            if target_language is None:
+                return default
+
+            if domain is None:
+                with_domain = ""
+            else:
+                with_domain = " with domain '%s'" % domain
+
+            stripped = default.rstrip('\n ')
+            return "%s ('%s' translation into '%s'%s)%s" % (
+                stripped, msgid, target_language, with_domain,
+                default[len(stripped):]
+                )
+
+        for input_path, output_path, language in self.find_files(ext):
+            # Make friendly title so we can locate the generated
+            # source when debugging
+            self.shortDescription = lambda: input_path
+
+            # Very implicitly enable implicit translation based on
+            # a string included in the input path:
+            implicit_i18n = 'implicit-i18n' in input_path
+            implicit_i18n_attrs = ("alt", "title") if implicit_i18n else ()
+
+            template = factory(
+                input_path,
+                keep_source=True,
+                strict=False,
+                implicit_i18n_translate=implicit_i18n,
+                implicit_i18n_attributes=implicit_i18n_attrs,
+                )
+
+            params = kwargs.copy()
+            params.update({
+                'translate': translate,
+                'target_language': language,
+                })
+
+            template.cook_check()
+
+            try:
+                got = template.render(**params)
+            except:
+                import traceback
+                e = traceback.format_exc()
+                self.fail("%s\n\n    Example source:\n\n%s" % (e, "\n".join(
+                    ["%#03.d%s" % (lineno + 1, line and " " + line or "")
+                     for (lineno, line) in
+                     enumerate(template.source.split(
+                         '\n'))])))
+
+            if isinstance(got, byte_string):
+                got = got.decode('utf-8')
+
+            from doctest import OutputChecker
+            checker = OutputChecker()
+
+            if not os.path.exists(output_path):
+                output = template.body
+            else:
+                with open(output_path, 'rb') as f:
+                    output = f.read()
+
+            from chameleon.utils import read_xml_encoding
+            from chameleon.utils import detect_encoding
+
+            if template.content_type == 'text/xml':
+                encoding = read_xml_encoding(output) or \
+                           template.default_encoding
+            else:
+                content_type, encoding = detect_encoding(
+                    output, template.default_encoding)
+
+            want = output.decode(encoding)
+
+            if checker.check_output(want, got, 0) is False:
+                from doctest import Example
+                example = Example(input_path, want)
+                diff = checker.output_difference(
+                    example, got, 0)
+                self.fail("(%s) - \n%s\n\nCode:\n%s" % (
+                    input_path, diff.rstrip('\n'),
+                    template.source.encode('utf-8')))
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tests/test_tokenizer.py b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_tokenizer.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tests/test_tokenizer.py
@@ -0,0 +1,47 @@
+import sys
+
+from unittest import TestCase
+
+
+class TokenizerTest(TestCase):
+    def test_sample_files(self):
+        import os
+        import traceback
+        path = os.path.join(os.path.dirname(__file__), "inputs")
+        for filename in os.listdir(path):
+            if not filename.endswith('.xml'):
+                continue
+            f = open(os.path.join(path, filename), 'rb')
+            source = f.read()
+            f.close()
+
+            from ..utils import read_encoded
+            try:
+                want = read_encoded(source)
+            except UnicodeDecodeError:
+                exc = sys.exc_info()[1]
+                self.fail("%s - %s" % (exc, filename))
+
+            from ..tokenize import iter_xml
+            try:
+                tokens = iter_xml(want)
+                got = "".join(tokens)
+            except:
+                self.fail(traceback.format_exc())
+
+            from doctest import OutputChecker
+            checker = OutputChecker()
+
+            if checker.check_output(want, got, 0) is False:
+                from doctest import Example
+                example = Example(f.name, want)
+                diff = checker.output_difference(
+                    example, got, 0)
+                self.fail("(%s) - \n%s" % (f.name, diff))
+
+    def test_token(self):
+        from chameleon.tokenize import Token
+        token = Token("abc", 1)
+
+        self.assertTrue(isinstance(token[1:], Token))
+        self.assertEqual(token[1:].pos, 2)
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/tokenize.py b/lib3/Chameleon-2.9.2/src/chameleon/tokenize.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/tokenize.py
@@ -0,0 +1,144 @@
+# http://code.activestate.com/recipes/65125-xml-lexing-shallow-parsing/
+# by Paul Prescod
+# licensed under the PSF License
+#
+# modified to capture all non-overlapping parts of tokens
+
+import re
+
+try:
+    str = unicode
+except NameError:
+    pass
+
+class recollector:
+    def __init__(self):
+        self.res = {}
+
+    def add(self, name, reg ):
+        re.compile(reg)  # check that it is valid
+        self.res[name] = reg % self.res
+
+collector = recollector()
+a = collector.add
+
+a("TextSE", "[^<]+")
+a("UntilHyphen", "[^-]*-")
+a("Until2Hyphens", "%(UntilHyphen)s(?:[^-]%(UntilHyphen)s)*-")
+a("CommentCE", "%(Until2Hyphens)s>?")
+a("UntilRSBs", "[^\\]]*](?:[^\\]]+])*]+")
+a("CDATA_CE", "%(UntilRSBs)s(?:[^\\]>]%(UntilRSBs)s)*>" )
+a("S", "[ \\n\\t\\r]+")
+a("Simple", "[^\"'>/]+")
+a("NameStrt", "[A-Za-z_:]|[^\\x00-\\x7F]")
+a("NameChar", "[A-Za-z0-9_:.-]|[^\\x00-\\x7F]")
+a("Name", "(?:%(NameStrt)s)(?:%(NameChar)s)*")
+a("QuoteSE", "\"[^\"]*\"|'[^']*'")
+a("DT_IdentSE" , "%(S)s%(Name)s(?:%(S)s(?:%(Name)s|%(QuoteSE)s))*" )
+a("MarkupDeclCE" , "(?:[^\\]\"'><]+|%(QuoteSE)s)*>" )
+a("S1", "[\\n\\r\\t ]")
+a("UntilQMs", "[^?]*\\?+")
+a("PI_Tail" , "\\?>|%(S1)s%(UntilQMs)s(?:[^>?]%(UntilQMs)s)*>" )
+a("DT_ItemSE",
+  "<(?:!(?:--%(Until2Hyphens)s>|[^-]%(MarkupDeclCE)s)|"
+  "\\?%(Name)s(?:%(PI_Tail)s))|%%%(Name)s;|%(S)s"
+)
+a("DocTypeCE" ,
+"%(DT_IdentSE)s(?:%(S)s)?(?:\\[(?:%(DT_ItemSE)s)*](?:%(S)s)?)?>?" )
+a("DeclCE",
+  "--(?:%(CommentCE)s)?|\\[CDATA\\[(?:%(CDATA_CE)s)?|"
+  "DOCTYPE(?:%(DocTypeCE)s)?")
+a("PI_CE", "%(Name)s(?:%(PI_Tail)s)?")
+a("EndTagCE", "%(Name)s(?:%(S)s)?>?")
+a("AttValSE", "\"[^\"]*\"|'[^']*'")
+a("ElemTagCE",
+  "(%(Name)s)(?:(%(S)s)(%(Name)s)(((?:%(S)s)?=(?:%(S)s)?)"
+  "(?:%(AttValSE)s|%(Simple)s)|(?!(?:%(S)s)?=)))*(?:%(S)s)?(/?>)?")
+a("MarkupSPE",
+  "<(?:!(?:%(DeclCE)s)?|"
+  "\\?(?:%(PI_CE)s)?|/(?:%(EndTagCE)s)?|(?:%(ElemTagCE)s)?)")
+a("XML_SPE", "%(TextSE)s|%(MarkupSPE)s")
+a("XML_MARKUP_ONLY_SPE", "%(MarkupSPE)s")
+a("ElemTagSPE", "<|%(Name)s")
+
+re_xml_spe = re.compile(collector.res['XML_SPE'])
+re_markup_only_spe = re.compile(collector.res['XML_MARKUP_ONLY_SPE'])
+
+
+def iter_xml(body, filename=None):
+    for match in re_xml_spe.finditer(body):
+        string = match.group()
+        pos = match.start()
+        yield Token(string, pos, body, filename)
+
+
+def iter_text(body, filename=None):
+    yield Token(body, 0, body, filename)
+
+
+class Token(str):
+    __slots__ = "pos", "source", "filename"
+
+    def __new__(cls, string, pos=0, source=None, filename=None):
+        inst = str.__new__(cls, string)
+        inst.pos = pos
+        inst.source = source
+        inst.filename = filename or ""
+        return inst
+
+    def __getslice__(self, i, j):
+        slice = str.__getslice__(self, i, j)
+        return Token(slice, self.pos + i, self.source, self.filename)
+
+    def __getitem__(self, index):
+        s = str.__getitem__(self, index)
+        if isinstance(index, slice):
+            return Token(
+                s, self.pos + (index.start or 0), self.source, self.filename)
+        return s
+
+    def __add__(self, other):
+        if other is None:
+            return self
+
+        return Token(
+            str.__add__(self, other), self.pos, self.source, self.filename)
+
+    def __eq__(self, other):
+        return str.__eq__(self, other)
+
+    def __hash__(self):
+        return str.__hash__(self)
+
+    def replace(self, *args):
+        s = str.replace(self, *args)
+        return Token(s, self.pos, self.source, self.filename)
+
+    def split(self, *args):
+        l = str.split(self, *args)
+        pos = self.pos
+        for i, s in enumerate(l):
+            l[i] = Token(s, pos, self.source, self.filename)
+            pos += len(s)
+        return l
+
+    def strip(self, *args):
+        return self.lstrip(*args).rstrip(*args)
+
+    def lstrip(self, *args):
+        s = str.lstrip(self, *args)
+        return Token(
+            s, self.pos + len(self) - len(s), self.source, self.filename)
+
+    def rstrip(self, *args):
+        s = str.rstrip(self, *args)
+        return Token(s, self.pos, self.source, self.filename)
+
+    @property
+    def location(self):
+        if self.source is None:
+            return 0, self.pos
+
+        body = self.source[:self.pos]
+        line = body.count('\n')
+        return line + 1, self.pos - body.rfind('\n', 0) - 1
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/utils.py b/lib3/Chameleon-2.9.2/src/chameleon/utils.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/utils.py
@@ -0,0 +1,429 @@
+import os
+import re
+import sys
+import codecs
+import logging
+
+from copy import copy
+
+version = sys.version_info[:3]
+
+try:
+    import ast as _ast
+except ImportError:
+    from chameleon import ast24 as _ast
+
+
+class ASTProxy(object):
+    aliases = {
+        # Python 3.3
+        'TryExcept': 'Try',
+        'TryFinally': 'Try',
+        }
+
+    def __getattr__(self, name):
+        return _ast.__dict__.get(name) or getattr(_ast, self.aliases[name])
+
+
+ast = ASTProxy()
+
+log = logging.getLogger('chameleon.utils')
+
+# Python 2
+if version < (3, 0, 0):
+    import htmlentitydefs
+    import __builtin__ as builtins
+
+    from .py25 import raise_with_traceback
+
+    chr = unichr
+    native_string = str
+    decode_string = unicode
+    encode_string = str
+    unicode_string = unicode
+    string_type = basestring
+    byte_string = str
+
+    def safe_native(s, encoding='utf-8'):
+        if not isinstance(s, unicode):
+            s = decode_string(s, encoding, 'replace')
+
+        return s.encode(encoding)
+
+# Python 3
+else:
+    from html import entities as htmlentitydefs
+    import builtins
+
+    byte_string = bytes
+    string_type = str
+    native_string = str
+    decode_string = bytes.decode
+    encode_string = lambda s: bytes(s, 'utf-8')
+    unicode_string = str
+
+    def safe_native(s, encoding='utf-8'):
+        if not isinstance(s, str):
+            s = decode_string(s, encoding, 'replace')
+
+        return s
+
+    def raise_with_traceback(exc, tb):
+        exc.__traceback__ = tb
+        raise exc
+
+def text_(s, encoding='latin-1', errors='strict'):
+    """ If ``s`` is an instance of ``byte_string``, return
+    ``s.decode(encoding, errors)``, otherwise return ``s``"""
+    if isinstance(s, byte_string):
+        return s.decode(encoding, errors)
+    return s
+
+entity_re = re.compile(r'&(#?)(x?)(\d{1,5}|\w{1,8});')
+
+module_cache = {}
+
+xml_prefixes = (
+    (codecs.BOM_UTF8, 'utf-8-sig'),
+    (codecs.BOM_UTF16_BE, 'utf-16-be'),
+    (codecs.BOM_UTF16_LE, 'utf-16-le'),
+    (codecs.BOM_UTF16, 'utf-16'),
+    (codecs.BOM_UTF32_BE, 'utf-32-be'),
+    (codecs.BOM_UTF32_LE, 'utf-32-le'),
+    (codecs.BOM_UTF32, 'utf-32'),
+    )
+
+
+def _has_encoding(encoding):
+    try:
+        "".encode(encoding)
+    except LookupError:
+        return False
+    else:
+        return True
+
+
+# Precomputed prefix table
+_xml_prefixes = tuple(
+    (bom, str('<?xml').encode(encoding), encoding)
+    for bom, encoding in reversed(xml_prefixes)
+    if _has_encoding(encoding)
+    )
+
+_xml_decl = encode_string("<?xml")
+
+RE_META = re.compile(
+    r'\s*<meta\s+http-equiv=["\']?Content-Type["\']?'
+    r'\s+content=["\']?([^;]+);\s*charset=([^"\']+)["\']?\s*/?\s*>\s*',
+    re.IGNORECASE
+    )
+
+RE_ENCODING = re.compile(
+    r'encoding\s*=\s*(?:"|\')(?P<encoding>[\w\-]+)(?:"|\')'.encode('ascii'),
+    re.IGNORECASE
+    )
+
+
+def read_encoded(data):
+    return read_bytes(data, "utf-8")[0]
+
+
+def read_bytes(body, default_encoding):
+    for bom, prefix, encoding in _xml_prefixes:
+        if body.startswith(bom):
+            document = body.decode(encoding)
+            return document, encoding, \
+                   "text/xml" if document.startswith("<?xml") else None
+
+        if prefix != encode_string('<?xml') and body.startswith(prefix):
+            return body.decode(encoding), encoding, "text/xml"
+
+    if body.startswith(_xml_decl):
+        content_type = "text/xml"
+
+        encoding = read_xml_encoding(body) or default_encoding
+    else:
+        content_type, encoding = detect_encoding(body, default_encoding)
+
+    return body.decode(encoding), encoding, content_type
+
+
+def detect_encoding(body, default_encoding):
+    if not isinstance(body, str):
+        body = body.decode('ascii', 'ignore')
+
+    match = RE_META.search(body)
+    if match is not None:
+        return match.groups()
+
+    return None, default_encoding
+
+
+def read_xml_encoding(body):
+    if body.startswith('<?xml'.encode('ascii')):
+        match = RE_ENCODING.search(body)
+        if match is not None:
+            return match.group('encoding').decode('ascii')
+
+
+def mangle(filename):
+    """Mangles template filename into top-level Python module name.
+
+    >>> mangle('hello_world.pt')
+    'hello_world'
+
+    >>> mangle('foo.bar.baz.pt')
+    'foo_bar_baz'
+
+    >>> mangle('foo-bar-baz.pt')
+    'foo_bar_baz'
+
+    """
+
+    base, ext = os.path.splitext(filename)
+    return base.replace('.', '_').replace('-', '_')
+
+
+def char2entity(c):
+    cp = ord(c)
+    name = htmlentitydefs.codepoint2name.get(cp)
+    return '&%s;' % name if name is not None else '&#%d;' % cp
+
+
+def substitute_entity(match, n2cp=htmlentitydefs.name2codepoint):
+    ent = match.group(3)
+
+    if match.group(1) == "#":
+        if match.group(2) == '':
+            return chr(int(ent))
+        elif match.group(2) == 'x':
+            return chr(int('0x' + ent, 16))
+    else:
+        cp = n2cp.get(ent)
+
+        if cp:
+            return chr(cp)
+        else:
+            return match.group()
+
+
+def create_formatted_exception(exc, cls, formatter):
+    try:
+        try:
+            new = type(cls.__name__, (cls, Exception), {
+                '__str__': formatter,
+                '__new__': BaseException.__new__,
+                '__module__': cls.__module__,
+                })
+        except TypeError:
+            new = cls
+
+        try:
+            inst = BaseException.__new__(new)
+        except TypeError:
+            inst = cls.__new__(new)
+
+        BaseException.__init__(inst, *exc.args)
+        inst.__dict__ = exc.__dict__
+
+        return inst
+    except ValueError:
+        name = type(exc).__name__
+        log.warn("Unable to copy exception of type '%s'." % name)
+        raise TypeError(exc)
+
+
+def unescape(string):
+    for name in ('lt', 'gt', 'quot'):
+        cp = htmlentitydefs.name2codepoint[name]
+        string = string.replace('&%s;' % name, chr(cp))
+
+    return string
+
+
+_concat = unicode_string("").join
+
+
+def join(stream):
+    """Concatenate stream.
+
+    >>> print(join(('Hello', ' ', 'world')))
+    Hello world
+
+    >>> join(('Hello', 0))
+    Traceback (most recent call last):
+     ...
+    TypeError: ... expected ...
+
+    """
+
+    try:
+        return _concat(stream)
+    except:
+        # Loop through stream and coerce each element into unicode;
+        # this should raise an exception
+        for element in stream:
+            unicode_string(element)
+
+        # In case it didn't, re-raise the original exception
+        raise
+
+
+def decode_htmlentities(string):
+    """
+    >>> native_string(decode_htmlentities('&amp;'))
+    '&'
+
+    """
+
+    decoded = entity_re.subn(substitute_entity, string)[0]
+
+    # preserve input token data
+    return string.replace(string, decoded)
+
+
+# Taken from zope.dottedname
+def _resolve_dotted(name, module=None):
+    name = name.split('.')
+    if not name[0]:
+        if module is None:
+            raise ValueError("relative name without base module")
+        module = module.split('.')
+        name.pop(0)
+        while not name[0]:
+            module.pop()
+            name.pop(0)
+        name = module + name
+
+    used = name.pop(0)
+    found = __import__(used)
+    for n in name:
+        used += '.' + n
+        try:
+            found = getattr(found, n)
+        except AttributeError:
+            __import__(used)
+            found = getattr(found, n)
+
+    return found
+
+
+def resolve_dotted(dotted):
+    if not dotted in module_cache:
+        resolved = _resolve_dotted(dotted)
+        module_cache[dotted] = resolved
+    return module_cache[dotted]
+
+
+def limit_string(s, max_length=53):
+    if len(s) > max_length:
+        return s[:max_length - 3] + '...'
+
+    return s
+
+
+def format_kwargs(kwargs):
+    items = []
+    for name, value in kwargs.items():
+        if isinstance(value, string_type):
+            short = limit_string(value)
+            items.append((name, short.replace('\n', '\\n')))
+        elif isinstance(value, (int, float)):
+            items.append((name, value))
+        elif isinstance(value, dict):
+            items.append((name, '{...} (%d)' % len(value)))
+        else:
+            items.append((name,
+                "<%s %s at %s>" % (
+                    type(value).__name__,
+                    getattr(value, '__name__', "-"),
+                    hex(abs(id(value))))))
+
+    return ["%s: %s" % item for item in items]
+
+
+class callablestr(str):
+    __slots__ = ()
+
+    def __call__(self):
+        return self
+
+
+class callableint(int):
+    __slots__ = ()
+
+    def __call__(self):
+        return self
+
+
+class descriptorstr(object):
+    __slots__ = "function", "__name__"
+
+    def __init__(self, function):
+        self.function = function
+        self.__name__ = function.__name__
+
+    def __get__(self, context, cls):
+        return callablestr(self.function(context))
+
+
+class descriptorint(object):
+    __slots__ = "function", "__name__"
+
+    def __init__(self, function):
+        self.function = function
+        self.__name__ = function.__name__
+
+    def __get__(self, context, cls):
+        return callableint(self.function(context))
+
+
+class DebuggingOutputStream(list):
+    def append(self, value):
+        if not isinstance(value, string_type):
+            raise TypeError(value)
+
+        unicode_string(value)
+        list.append(self, value)
+
+
+class Scope(dict):
+    set_local = setLocal = dict.__setitem__
+
+    __slots__ = "set_global",
+
+    def __new__(cls, *args):
+        inst = dict.__new__(cls, *args)
+        inst.set_global = inst.__setitem__
+        return inst
+
+    def __getitem__(self, key):
+        try:
+            return dict.__getitem__(self, key)
+        except KeyError:
+            raise NameError(key)
+
+    @property
+    def vars(self):
+        return self
+
+    def copy(self):
+        inst = Scope(self)
+        inst.set_global = self.set_global
+        return inst
+
+
+class ListDictProxy(object):
+    def __init__(self, l):
+        self._l = l
+
+    def get(self, key):
+        return self._l[-1].get(key)
+
+
+class Markup(unicode_string):
+    def __html__(self):
+        return unicode_string(self)
+
+    def __repr__(self):
+        return "s'%s'" % self.s
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/zpt/__init__.py b/lib3/Chameleon-2.9.2/src/chameleon/zpt/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/zpt/__init__.py
@@ -0,0 +1,1 @@
+#
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/zpt/loader.py b/lib3/Chameleon-2.9.2/src/chameleon/zpt/loader.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/zpt/loader.py
@@ -0,0 +1,30 @@
+from chameleon.loader import TemplateLoader as BaseLoader
+from chameleon.zpt import template
+
+
+class TemplateLoader(BaseLoader):
+    formats = {
+        "xml": template.PageTemplateFile,
+        "text": template.PageTextTemplateFile,
+        }
+
+    default_format = "xml"
+
+    def __init__(self, *args, **kwargs):
+        formats = kwargs.pop('formats', None)
+        if formats is not None:
+            self.formats = formats
+
+        super(TemplateLoader, self).__init__(*args, **kwargs)
+
+    def load(self, filename, format=None):
+        """Load and return a template file.
+
+        The format parameter determines will parse the file. Valid
+        options are `xml` and `text`.
+        """
+
+        cls = self.formats[format or self.default_format]
+        return super(TemplateLoader, self).load(filename, cls)
+
+    __getitem__ = load
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/zpt/program.py b/lib3/Chameleon-2.9.2/src/chameleon/zpt/program.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/zpt/program.py
@@ -0,0 +1,751 @@
+import re
+
+try:
+    import ast
+except ImportError:
+    from chameleon import ast24 as ast
+
+try:
+    str = unicode
+except NameError:
+    long = int
+
+from functools import partial
+from copy import copy
+
+from ..program import ElementProgram
+
+from ..namespaces import XML_NS
+from ..namespaces import XMLNS_NS
+from ..namespaces import I18N_NS as I18N
+from ..namespaces import TAL_NS as TAL
+from ..namespaces import METAL_NS as METAL
+from ..namespaces import META_NS as META
+
+from ..astutil import Static
+from ..astutil import parse
+from ..astutil import marker
+
+from .. import tal
+from .. import metal
+from .. import i18n
+from .. import nodes
+
+from ..exc import LanguageError
+from ..exc import ParseError
+from ..exc import CompilationError
+
+from ..utils import decode_htmlentities
+
+try:
+    str = unicode
+except NameError:
+    long = int
+
+
+missing = object()
+
+re_trim = re.compile(r'($\s+|\s+^)', re.MULTILINE)
+
+def skip(node):
+    return node
+
+
+def wrap(node, *wrappers):
+    for wrapper in reversed(wrappers):
+        node = wrapper(node)
+    return node
+
+
+def validate_attributes(attributes, namespace, whitelist):
+    for ns, name in attributes:
+        if ns == namespace and name not in whitelist:
+            raise CompilationError(
+                "Bad attribute for namespace '%s'" % ns, name
+                )
+
+
+class MacroProgram(ElementProgram):
+    """Visitor class that generates a program for the ZPT language."""
+
+    DEFAULT_NAMESPACES = {
+        'xmlns': XMLNS_NS,
+        'xml': XML_NS,
+        'tal': TAL,
+        'metal': METAL,
+        'i18n': I18N,
+        'meta': META,
+        }
+
+    DROP_NS = TAL, METAL, I18N, META
+
+    VARIABLE_BLACKLIST = "default", "repeat", "nothing", \
+                         "convert", "decode", "translate"
+
+    _interpolation_enabled = True
+    _whitespace = "\n"
+    _last = ""
+
+    # Macro name (always trivial for a macro program)
+    name = None
+
+    # This default marker value has the semantics that if an
+    # expression evaluates to that value, the expression default value
+    # is returned. For an attribute, if there is no default, this
+    # means that the attribute is dropped.
+    default_marker = None
+
+    # Escape mode (true value means XML-escape)
+    escape = True
+
+    # Attributes which should have boolean behavior (on true, the
+    # value takes the attribute name, on false, the attribute is
+    # dropped)
+    boolean_attributes = set()
+
+    # If provided, this should be a set of attributes for implicit
+    # translation. Any attribute whose name is included in the set
+    # will be translated even without explicit markup. Note that all
+    # values should be lowercase strings.
+    implicit_i18n_attributes = set()
+
+    # If set, text will be translated even without explicit markup.
+    implicit_i18n_translate = False
+
+    # If set, additional attribute whitespace will be stripped.
+    trim_attribute_space = False
+
+    def __init__(self, *args, **kwargs):
+        # Internal array for switch statements
+        self._switches = []
+
+        # Internal array for current use macro level
+        self._use_macro = []
+
+        # Internal array for current interpolation status
+        self._interpolation = [True]
+
+        # Internal dictionary of macro definitions
+        self._macros = {}
+
+        # Apply default values from **kwargs to self
+        self._pop_defaults(
+            kwargs,
+            'boolean_attributes',
+            'default_marker',
+            'escape',
+            'implicit_i18n_translate',
+            'implicit_i18n_attributes',
+            'trim_attribute_space',
+            )
+
+        super(MacroProgram, self).__init__(*args, **kwargs)
+
+    @property
+    def macros(self):
+        macros = list(self._macros.items())
+        macros.append((None, nodes.Sequence(self.body)))
+
+        return tuple(
+            nodes.Macro(name, [nodes.Context(node)])
+            for name, node in macros
+            )
+
+    def visit_default(self, node):
+        return nodes.Text(node)
+
+    def visit_element(self, start, end, children):
+        ns = start['ns_attrs']
+
+        for (prefix, attr), encoded in tuple(ns.items()):
+            if prefix == TAL:
+                ns[prefix, attr] = decode_htmlentities(encoded)
+
+        # Validate namespace attributes
+        validate_attributes(ns, TAL, tal.WHITELIST)
+        validate_attributes(ns, METAL, metal.WHITELIST)
+        validate_attributes(ns, I18N, i18n.WHITELIST)
+
+        # Check attributes for language errors
+        self._check_attributes(start['namespace'], ns)
+
+        # Remember whitespace for item repetition
+        if self._last is not None:
+            self._whitespace = "\n" + " " * len(self._last.rsplit('\n', 1)[-1])
+
+        # Set element-local whitespace
+        whitespace = self._whitespace
+
+        # Set up switch
+        try:
+            clause = ns[TAL, 'switch']
+        except KeyError:
+            switch = None
+        else:
+            switch = nodes.Value(clause)
+
+        self._switches.append(switch)
+
+        body = []
+
+        # Include macro
+        use_macro = ns.get((METAL, 'use-macro'))
+        extend_macro = ns.get((METAL, 'extend-macro'))
+        if use_macro or extend_macro:
+            slots = []
+            self._use_macro.append(slots)
+
+            if use_macro:
+                inner = nodes.UseExternalMacro(
+                    nodes.Value(use_macro), slots, False
+                    )
+            else:
+                inner = nodes.UseExternalMacro(
+                    nodes.Value(extend_macro), slots, True
+                    )
+        # -or- include tag
+        else:
+            content = nodes.Sequence(body)
+
+            # tal:content
+            try:
+                clause = ns[TAL, 'content']
+            except KeyError:
+                pass
+            else:
+                key, value = tal.parse_substitution(clause)
+                xlate = True if ns.get((I18N, 'translate')) == '' else False
+                content = self._make_content_node(value, content, key, xlate)
+
+                if end is None:
+                    # Make sure start-tag has opening suffix.
+                    start['suffix']  = ">"
+
+                    # Explicitly set end-tag.
+                    end = {
+                        'prefix': '</',
+                        'name': start['name'],
+                        'space': '',
+                        'suffix': '>'
+                        }
+
+            # i18n:translate
+            try:
+                clause = ns[I18N, 'translate']
+            except KeyError:
+                pass
+            else:
+                dynamic = ns.get((TAL, 'content')) or ns.get((TAL, 'replace'))
+
+                if not dynamic:
+                    content = nodes.Translate(clause, content)
+
+            # tal:attributes
+            try:
+                clause = ns[TAL, 'attributes']
+            except KeyError:
+                TAL_ATTRIBUTES = {}
+            else:
+                TAL_ATTRIBUTES = tal.parse_attributes(clause)
+
+            # i18n:attributes
+            try:
+                clause = ns[I18N, 'attributes']
+            except KeyError:
+                I18N_ATTRIBUTES = {}
+            else:
+                I18N_ATTRIBUTES = i18n.parse_attributes(clause)
+
+            # Prepare attributes from TAL language
+            prepared = tal.prepare_attributes(
+                start['attrs'], TAL_ATTRIBUTES,
+                I18N_ATTRIBUTES, ns, self.DROP_NS
+                )
+
+            # Create attribute nodes
+            STATIC_ATTRIBUTES = self._create_static_attributes(prepared)
+            ATTRIBUTES = self._create_attributes_nodes(
+                prepared, I18N_ATTRIBUTES
+                )
+
+            # Start- and end nodes
+            start_tag = nodes.Start(
+                start['name'],
+                self._maybe_trim(start['prefix']),
+                self._maybe_trim(start['suffix']),
+                ATTRIBUTES
+                )
+
+            end_tag = nodes.End(
+                end['name'],
+                end['space'],
+                self._maybe_trim(end['prefix']),
+                self._maybe_trim(end['suffix']),
+                ) if end is not None else None
+
+            # tal:omit-tag
+            try:
+                clause = ns[TAL, 'omit-tag']
+            except KeyError:
+                omit = False
+            else:
+                clause = clause.strip()
+
+                if clause == "":
+                    omit = True
+                else:
+                    expression = nodes.Negate(nodes.Value(clause))
+                    omit = expression
+
+                    # Wrap start- and end-tags in condition
+                    start_tag = nodes.Condition(expression, start_tag)
+
+                    if end_tag is not None:
+                        end_tag = nodes.Condition(expression, end_tag)
+
+            if omit is True or start['namespace'] in self.DROP_NS:
+                inner = content
+            else:
+                inner = nodes.Element(
+                    start_tag,
+                    end_tag,
+                    content,
+                    )
+
+                # Assign static attributes dictionary to "attrs" value
+                inner = nodes.Define(
+                    [nodes.Alias(["attrs"], STATIC_ATTRIBUTES)],
+                    inner,
+                    )
+
+                if omit is not False:
+                    inner = nodes.Cache([omit], inner)
+
+            # tal:replace
+            try:
+                clause = ns[TAL, 'replace']
+            except KeyError:
+                pass
+            else:
+                key, value = tal.parse_substitution(clause)
+                xlate = True if ns.get((I18N, 'translate')) == '' else False
+                inner = self._make_content_node(value, inner, key, xlate)
+
+        # metal:define-slot
+        try:
+            clause = ns[METAL, 'define-slot']
+        except KeyError:
+            DEFINE_SLOT = skip
+        else:
+            DEFINE_SLOT = partial(nodes.DefineSlot, clause)
+
+        # tal:define
+        try:
+            clause = ns[TAL, 'define']
+        except KeyError:
+            DEFINE = skip
+        else:
+            defines = tal.parse_defines(clause)
+            if defines is None:
+                raise ParseError("Invalid define syntax.", clause)
+
+            DEFINE = partial(
+                nodes.Define,
+                [nodes.Assignment(
+                    names, nodes.Value(expr), context == "local")
+                 for (context, names, expr) in defines],
+                )
+
+        # tal:case
+        try:
+            clause = ns[TAL, 'case']
+        except KeyError:
+            CASE = skip
+        else:
+            value = nodes.Value(clause)
+            for switch in reversed(self._switches):
+                if switch is not None:
+                    break
+            else:
+                raise LanguageError(
+                    "Must define switch on a parent element.", clause
+                    )
+
+            CASE = lambda node: nodes.Define(
+                [nodes.Assignment(["default"], switch, True)],
+                nodes.Condition(
+                    nodes.Equality(switch, value),
+                    node,
+                    )
+                )
+
+        # tal:repeat
+        try:
+            clause = ns[TAL, 'repeat']
+        except KeyError:
+            REPEAT = skip
+        else:
+            defines = tal.parse_defines(clause)
+            assert len(defines) == 1
+            context, names, expr = defines[0]
+
+            expression = nodes.Value(expr)
+
+            REPEAT = partial(
+                nodes.Repeat,
+                names,
+                expression,
+                context == "local",
+                whitespace
+                )
+
+        # tal:condition
+        try:
+            clause = ns[TAL, 'condition']
+        except KeyError:
+            CONDITION = skip
+        else:
+            expression = nodes.Value(clause)
+            CONDITION = partial(nodes.Condition, expression)
+
+        # tal:switch
+        if switch is None:
+            SWITCH = skip
+        else:
+            SWITCH = partial(nodes.Cache, [switch])
+
+        # i18n:domain
+        try:
+            clause = ns[I18N, 'domain']
+        except KeyError:
+            DOMAIN = skip
+        else:
+            DOMAIN = partial(nodes.Domain, clause)
+
+        # i18n:name
+        try:
+            clause = ns[I18N, 'name']
+        except KeyError:
+            NAME = skip
+        else:
+            if not clause.strip():
+                NAME = skip
+            else:
+                NAME = partial(nodes.Name, clause)
+
+        # The "slot" node next is the first node level that can serve
+        # as a macro slot
+        slot = wrap(
+            inner,
+            DEFINE_SLOT,
+            DEFINE,
+            CASE,
+            CONDITION,
+            REPEAT,
+            SWITCH,
+            DOMAIN,
+            )
+
+        # metal:fill-slot
+        try:
+            clause = ns[METAL, 'fill-slot']
+        except KeyError:
+            pass
+        else:
+            index = -(1 + int(bool(use_macro or extend_macro)))
+
+            try:
+                slots = self._use_macro[index]
+            except IndexError:
+                raise LanguageError(
+                    "Cannot use metal:fill-slot without metal:use-macro.",
+                    clause
+                    )
+
+            slots = self._use_macro[index]
+            slots.append(nodes.FillSlot(clause, slot))
+
+        # metal:define-macro
+        try:
+            clause = ns[METAL, 'define-macro']
+        except KeyError:
+            pass
+        else:
+            self._macros[clause] = slot
+            slot = nodes.UseInternalMacro(clause)
+
+        slot = wrap(
+            slot,
+            NAME
+            )
+
+        # tal:on-error
+        try:
+            clause = ns[TAL, 'on-error']
+        except KeyError:
+            ON_ERROR = skip
+        else:
+            key, value = tal.parse_substitution(clause)
+            translate = True if ns.get((I18N, 'translate')) == '' else False
+
+            fallback = self._make_content_node(value, None, key, translate)
+
+            if omit is False and start['namespace'] not in self.DROP_NS:
+                start_tag = copy(start_tag)
+
+                start_tag.attributes = filter(
+                    lambda attribute: isinstance(attribute, nodes.Attribute) and \
+                                      isinstance(attribute.expression, ast.Str),
+                    start_tag.attributes
+                    )
+
+                if end_tag is None:
+                    # Make sure start-tag has opening suffix. We don't
+                    # allow self-closing element here.
+                    start_tag.suffix  = ">"
+
+                    # Explicitly set end-tag.
+                    end_tag = nodes.End(start_tag.name, '', '</', '>',)
+
+                fallback = nodes.Element(
+                    start_tag,
+                    end_tag,
+                    fallback,
+                )
+
+            ON_ERROR = partial(nodes.OnError, fallback, 'error')
+
+        clause = ns.get((META, 'interpolation'))
+        if clause in ('false', 'off'):
+            INTERPOLATION = False
+        elif clause in ('true', 'on'):
+            INTERPOLATION = True
+        elif clause is None:
+            INTERPOLATION = self._interpolation[-1]
+        else:
+            raise LanguageError("Bad interpolation setting.", clause)
+
+        self._interpolation.append(INTERPOLATION)
+
+        # Visit content body
+        for child in children:
+            body.append(self.visit(*child))
+
+        self._switches.pop()
+        self._interpolation.pop()
+
+        if use_macro:
+            self._use_macro.pop()
+
+        return wrap(
+            slot,
+            ON_ERROR
+            )
+
+    def visit_start_tag(self, start):
+        return self.visit_element(start, None, [])
+
+    def visit_cdata(self, node):
+        if not self._interpolation[-1] or not '${' in node:
+            return nodes.Text(node)
+
+        expr = nodes.Substitution(node, ())
+        return nodes.Interpolation(expr, True, False)
+
+    def visit_comment(self, node):
+        if node.startswith('<!--!'):
+            return
+
+        if node.startswith('<!--?'):
+            return nodes.Text('<!--' + node.lstrip('<!-?'))
+
+        if not self._interpolation[-1] or not '${' in node:
+            return nodes.Text(node)
+
+        char_escape = ('&', '<', '>') if self.escape else ()
+        expression = nodes.Substitution(node[4:-3], char_escape)
+
+        return nodes.Sequence(
+            [nodes.Text(node[:4]),
+             nodes.Interpolation(expression, True, False),
+             nodes.Text(node[-3:])
+             ])
+
+    def visit_processing_instruction(self, node):
+        if node['name'] != 'python':
+            text = '<?' + node['name'] + node['text'] + '?>'
+            return self.visit_text(text)
+
+        return nodes.CodeBlock(node['text'])
+
+    def visit_text(self, node):
+        self._last = node
+
+        translation = self.implicit_i18n_translate
+
+        if self._interpolation[-1] and '${' in node:
+            char_escape = ('&', '<', '>') if self.escape else ()
+            expression = nodes.Substitution(node, char_escape)
+            return nodes.Interpolation(expression, True, translation)
+
+        if not translation:
+            return nodes.Text(node)
+
+        seq = []
+        while node:
+            m = re.search('\s+', node)
+            if m is not None:
+                s = m.start()
+                if s:
+                    t = node[:s]
+                    seq.append(nodes.Translate(t, nodes.Text(t)))
+
+                e = m.end()
+                whitespace = nodes.Text(node[s:e])
+                seq.append(whitespace)
+
+                if e < len(node):
+                    node = node[e:]
+                    continue
+
+            else:
+                seq.append(nodes.Translate(node, nodes.Text(node)))
+
+            break
+
+        return nodes.Sequence(seq)
+
+    def _pop_defaults(self, kwargs, *attributes):
+        for attribute in attributes:
+            default = getattr(self, attribute)
+            value = kwargs.pop(attribute, default)
+            setattr(self, attribute, value)
+
+    def _check_attributes(self, namespace, ns):
+        if namespace in self.DROP_NS and ns.get((TAL, 'attributes')):
+            raise LanguageError(
+                "Dynamic attributes not allowed on elements of "
+                "the namespace: %s." % namespace,
+                ns[TAL, 'attributes'],
+                )
+
+        script = ns.get((TAL, 'script'))
+        if script is not None:
+            raise LanguageError(
+                "The script attribute is unsupported.", script)
+
+        tal_content = ns.get((TAL, 'content'))
+        if tal_content and ns.get((TAL, 'replace')):
+            raise LanguageError(
+                "You cannot use tal:content and tal:replace at the same time.",
+                tal_content
+                )
+
+        if tal_content and ns.get((I18N, 'translate')):
+            raise LanguageError(
+                "You cannot use tal:content with non-trivial i18n:translate.",
+                tal_content
+                )
+
+    def _make_content_node(self, expression, default, key, translate):
+        value = nodes.Value(expression)
+        char_escape = ('&', '<', '>') if key == 'text' else ()
+        content = nodes.Content(value, char_escape, translate)
+
+        if default is not None:
+            content = nodes.Condition(
+                nodes.Identity(value, marker("default")),
+                default,
+                content,
+                )
+
+            # Cache expression to avoid duplicate evaluation
+            content = nodes.Cache([value], content)
+
+            # Define local marker "default"
+            content = nodes.Define(
+                [nodes.Alias(["default"], marker("default"))],
+                content
+                )
+
+        return content
+
+    def _create_attributes_nodes(self, prepared, I18N_ATTRIBUTES):
+        attributes = []
+
+        for name, text, quote, space, eq, expr in prepared:
+            implicit_i18n = name.lower() in self.implicit_i18n_attributes
+
+            char_escape = ('&', '<', '>', quote)
+
+            # Use a provided default text as the default marker
+            # (aliased to the name ``default``), otherwise use the
+            # program's default marker value.
+            if text is not None:
+                default_marker = ast.Str(s=text)
+            else:
+                default_marker = self.default_marker
+
+            msgid = I18N_ATTRIBUTES.get(name, missing)
+
+            # If (by heuristic) ``text`` contains one or more
+            # interpolation expressions, apply interpolation
+            # substitution to the text
+            if expr is None and text is not None and '${' in text:
+                expr = nodes.Substitution(text, char_escape, None)
+                translation = implicit_i18n and msgid is missing
+                value = nodes.Interpolation(expr, True, translation)
+                default_marker = self.default_marker
+
+            # If the expression is non-trivial, the attribute is
+            # dynamic (computed).
+            elif expr is not None:
+                if name in self.boolean_attributes:
+                    value = nodes.Boolean(expr, name)
+                else:
+                    if text is not None:
+                        default = default_marker
+                    else:
+                        default = None
+
+                    value = nodes.Substitution(expr, char_escape, default)
+
+            # Otherwise, it's a static attribute.
+            else:
+                value = ast.Str(s=text)
+                if msgid is missing and implicit_i18n:
+                    msgid = text
+
+            # If translation is required, wrap in a translation
+            # clause
+            if msgid is not missing:
+                value = nodes.Translate(msgid, value)
+
+            space = self._maybe_trim(space)
+            attribute = nodes.Attribute(name, value, quote, eq, space)
+
+            if not isinstance(value, ast.Str):
+                # Always define a ``default`` alias for non-static
+                # expressions.
+                attribute = nodes.Define(
+                    [nodes.Alias(["default"], default_marker)],
+                    attribute,
+                    )
+
+            attributes.append(attribute)
+
+        return attributes
+
+    def _create_static_attributes(self, prepared):
+        static_attrs = {}
+
+        for name, text, quote, space, eq, expr in prepared:
+            static_attrs[name] = text if text is not None else expr
+
+        return Static(parse(repr(static_attrs)).body)
+
+    def _maybe_trim(self, string):
+        if self.trim_attribute_space:
+            return re_trim.sub(" ", string)
+
+        return string
diff --git a/lib3/Chameleon-2.9.2/src/chameleon/zpt/template.py b/lib3/Chameleon-2.9.2/src/chameleon/zpt/template.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/chameleon/zpt/template.py
@@ -0,0 +1,409 @@
+try:
+    import ast
+except ImportError:
+    from chameleon import ast24 as ast
+
+from functools import partial
+from os.path import dirname
+
+from ..i18n import fast_translate
+from ..tales import PythonExpr
+from ..tales import StringExpr
+from ..tales import NotExpr
+from ..tales import ExistsExpr
+from ..tales import ImportExpr
+from ..tales import ProxyExpr
+from ..tales import StructureExpr
+from ..tales import ExpressionParser
+
+from ..tal import RepeatDict
+
+from ..template import BaseTemplate
+from ..template import BaseTemplateFile
+from ..compiler import ExpressionEngine
+from ..loader import TemplateLoader
+from ..astutil import Builtin
+from ..utils import decode_string
+from ..utils import string_type
+
+from .program import MacroProgram
+
+try:
+    bytes
+except NameError:
+    bytes = str
+
+
+class PageTemplate(BaseTemplate):
+    """Constructor for the page template language.
+
+    Takes a string input as the only positional argument::
+
+      template = PageTemplate("<div>Hello, ${name}.</div>")
+
+    Configuration (keyword arguments):
+
+      ``default_expression``
+
+        Set the default expression type. The default setting is
+        ``python``.
+
+      ``encoding``
+
+        The default text substitution value is a unicode string on
+        Python 2 or simply string on Python 3.
+
+        Pass an encoding to allow encoded byte string input
+        (e.g. UTF-8).
+
+      ``literal_false``
+
+        Attributes are not dropped for a value of ``False``. Instead,
+        the value is coerced to a string.
+
+        This setting exists to provide compatibility with the
+        reference implementation.
+
+      ``boolean_attributes``
+
+        Attributes included in this set are treated as booleans: if a
+        true value is provided, the attribute value is the attribute
+        name, e.g.::
+
+            boolean_attributes = {"selected"}
+
+        If we insert an attribute with the name "selected" and
+        provide a true value, the attribute will be rendered::
+
+            selected="selected"
+
+        If a false attribute is provided (including the empty string),
+        the attribute is dropped.
+
+        The special return value ``default`` drops or inserts the
+        attribute based on the value element attribute value.
+
+      ``translate``
+
+        Use this option to set a translation function.
+
+        Example::
+
+          def translate(msgid, domain=None, mapping=None, default=None, context=None):
+              ...
+              return translation
+
+        Note that if ``target_language`` is provided at render time,
+        the translation function must support this argument.
+
+      ``implicit_i18n_translate``
+
+        Enables implicit translation for text appearing inside
+        elements. Default setting is ``False``.
+
+        While implicit translation does work for text that includes
+        expression interpolation, each expression must be simply a
+        variable name (e.g. ``${foo}``); otherwise, the text will not
+        be marked for translation.
+
+      ``implicit_i18n_attributes``
+
+        Any attribute contained in this set will be marked for
+        implicit translation. Each entry must be a lowercase string.
+
+        Example::
+
+          implicit_i18n_attributes = set(['alt', 'title'])
+
+      ``strict``
+
+        Enabled by default. If disabled, expressions are only required
+        to be valid at evaluation time.
+
+        This setting exists to provide compatibility with the
+        reference implementation which compiles expressions at
+        evaluation time.
+
+      ``trim_attribute_space``
+
+        If set, additional attribute whitespace will be stripped.
+
+    Output is unicode on Python 2 and string on Python 3.
+    """
+
+    expression_types = {
+        'python': PythonExpr,
+        'string': StringExpr,
+        'not': NotExpr,
+        'exists': ExistsExpr,
+        'import': ImportExpr,
+        'structure': StructureExpr,
+        }
+
+    default_expression = 'python'
+
+    translate = staticmethod(fast_translate)
+
+    encoding = None
+
+    boolean_attributes = set()
+
+    literal_false = False
+
+    mode = "xml"
+
+    implicit_i18n_translate = False
+
+    implicit_i18n_attributes = set()
+
+    trim_attribute_space = False
+
+    def __init__(self, body, **config):
+        self.macros = Macros(self)
+        super(PageTemplate, self).__init__(body, **config)
+
+    def __getitem__(self, name):
+        return self.macros[name]
+
+    @property
+    def builtins(self):
+        return self._builtins()
+
+    @property
+    def engine(self):
+        if self.literal_false:
+            default_marker = ast.Str(s="__default__")
+        else:
+            default_marker = Builtin("False")
+
+        return partial(
+            ExpressionEngine,
+            self.expression_parser,
+            default_marker=default_marker,
+            )
+
+    @property
+    def expression_parser(self):
+        return ExpressionParser(self.expression_types, self.default_expression)
+
+    def parse(self, body):
+        if self.literal_false:
+            default_marker = ast.Str(s="__default__")
+        else:
+            default_marker = Builtin("False")
+
+        return MacroProgram(
+            body, self.mode, self.filename,
+            escape=True if self.mode == "xml" else False,
+            default_marker=default_marker,
+            boolean_attributes=self.boolean_attributes,
+            implicit_i18n_translate=self.implicit_i18n_translate,
+            implicit_i18n_attributes=self.implicit_i18n_attributes,
+            trim_attribute_space=self.trim_attribute_space,
+            )
+
+    def render(self, encoding=None, translate=None, **vars):
+        """Render template to string.
+
+        The ``encoding`` and ``translate`` arguments are documented in
+        the template class constructor. If passed to this method, they
+        are used instead of the class defaults.
+
+        Additional arguments:
+
+          ``target_language``
+
+            This argument will be partially applied to the translation
+            function.
+
+            An alternative is thus to simply provide a custom
+            translation function which includes this information or
+            relies on a different mechanism.
+
+        """
+
+        non_trivial_translate = translate is not None
+        translate = translate if non_trivial_translate else self.translate or \
+                    type(self).translate
+
+        # Curry language parameter if non-trivial
+        target_language = vars.get('target_language')
+        if target_language is not None:
+            translate = partial(translate, target_language=target_language)
+
+        encoding = encoding if encoding is not None else self.encoding
+        if encoding is not None:
+            txl = translate
+
+            def translate(msgid, **kwargs):
+                if isinstance(msgid, bytes):
+                    msgid = decode_string(msgid, encoding)
+                return txl(msgid, **kwargs)
+
+            def decode(inst):
+                return decode_string(inst, encoding, 'ignore')
+        else:
+            decode = decode_string
+
+        setdefault = vars.setdefault
+        setdefault("__translate", translate)
+        setdefault("__convert", translate)
+        setdefault("__decode", decode)
+
+        if non_trivial_translate:
+            vars['translate'] = translate
+
+        # Make sure we have a repeat dictionary
+        if 'repeat' not in vars: vars['repeat'] = RepeatDict({})
+
+        return super(PageTemplate, self).render(**vars)
+
+    def include(self, *args, **kwargs):
+        self.cook_check()
+        self._render(*args, **kwargs)
+
+    def _builtins(self):
+        return {
+            'template': self,
+            'macros': self.macros,
+            'nothing': None,
+            }
+
+
+class PageTemplateFile(PageTemplate, BaseTemplateFile):
+    """File-based constructor.
+
+    Takes a string input as the only positional argument::
+
+      template = PageTemplateFile(absolute_path)
+
+    Note that the file-based template class comes with the expression
+    type ``load`` which loads templates relative to the provided
+    filename.
+
+    Below are listed the configuration arguments specific to
+    file-based templates; see the string-based template class for
+    general options and documentation:
+
+    Configuration (keyword arguments):
+
+      ``loader_class``
+
+        The provided class will be used to create the template loader
+        object. The default implementation supports relative and
+        absolute path specs.
+
+        The class must accept keyword arguments ``search_path``
+        (sequence of paths to search for relative a path spec) and
+        ``default_extension`` (if provided, this should be added to
+        any path spec).
+
+      ``prepend_relative_search_path``
+
+        Inserts the path relative to the provided template file path
+        into the template search path.
+
+        The default setting is ``True``.
+
+      ``search_path``
+
+        If provided, this is used as the search path for the ``load:``
+        expression. It must be a string or an iterable yielding a
+        sequence of strings.
+
+    """
+
+    expression_types = PageTemplate.expression_types.copy()
+    expression_types['load'] = partial(ProxyExpr, '__loader')
+
+    prepend_relative_search_path = True
+
+    def __init__(self, filename, search_path=None, loader_class=TemplateLoader,
+                 **config):
+        super(PageTemplateFile, self).__init__(filename, **config)
+
+        if search_path is None:
+            search_path = []
+        else:
+            if isinstance(search_path, string_type):
+                search_path = [search_path]
+            else:
+                search_path = list(search_path)
+
+        # If the flag is set (this is the default), prepend the path
+        # relative to the template file to the search path
+        if self.prepend_relative_search_path:
+            path = dirname(self.filename)
+            search_path.insert(0, path)
+
+        loader = loader_class(search_path=search_path, **config)
+        template_class = type(self)
+
+        # Bind relative template loader instance to the same template
+        # class, providing the same keyword arguments.
+        self._loader = loader.bind(template_class)
+
+    def _builtins(self):
+        d = super(PageTemplateFile, self)._builtins()
+        d['__loader'] = self._loader
+        return d
+
+
+class PageTextTemplate(PageTemplate):
+    """Text-based template class.
+
+    Takes a non-XML input::
+
+      template = PageTextTemplate("Hello, ${name}.")
+
+    This is similar to the standard library class ``string.Template``,
+    but uses the expression engine to substitute variables.
+    """
+
+    mode = "text"
+
+
+class PageTextTemplateFile(PageTemplateFile):
+    """File-based constructor."""
+
+    mode = "text"
+
+    def render(self, **vars):
+        result = super(PageTextTemplateFile, self).render(**vars)
+        return result.encode(self.encoding or 'utf-8')
+
+
+class Macro(object):
+    __slots__ = "include",
+
+    def __init__(self, render):
+        self.include = render
+
+
+class Macros(object):
+    __slots__ = "template",
+
+    def __init__(self, template):
+        self.template = template
+
+    def __getitem__(self, name):
+        name = name.replace('-', '_')
+        self.template.cook_check()
+
+        try:
+            function = getattr(self.template, "_render_%s" % name)
+        except AttributeError:
+            raise KeyError(
+                "Macro does not exist: '%s'." % name)
+
+        return Macro(function)
+
+    @property
+    def names(self):
+        self.template.cook_check()
+
+        result = []
+        for name in self.template.__dict__:
+            if name.startswith('_render_'):
+                result.append(name[8:])
+        return result
diff --git a/lib3/Chameleon-2.9.2/src/ordereddict.py b/lib3/Chameleon-2.9.2/src/ordereddict.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/ordereddict.py
@@ -0,0 +1,127 @@
+# Copyright (c) 2009 Raymond Hettinger
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+#     The above copyright notice and this permission notice shall be
+#     included in all copies or substantial portions of the Software.
+#
+#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+#     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+#     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+#     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+#     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+#     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+#     OTHER DEALINGS IN THE SOFTWARE.
+
+from UserDict import DictMixin
+
+class OrderedDict(dict, DictMixin):
+
+    def __init__(self, *args, **kwds):
+        if len(args) > 1:
+            raise TypeError('expected at most 1 arguments, got %d' % len(args))
+        try:
+            self.__end
+        except AttributeError:
+            self.clear()
+        self.update(*args, **kwds)
+
+    def clear(self):
+        self.__end = end = []
+        end += [None, end, end]         # sentinel node for doubly linked list
+        self.__map = {}                 # key --> [key, prev, next]
+        dict.clear(self)
+
+    def __setitem__(self, key, value):
+        if key not in self:
+            end = self.__end
+            curr = end[1]
+            curr[2] = end[1] = self.__map[key] = [key, curr, end]
+        dict.__setitem__(self, key, value)
+
+    def __delitem__(self, key):
+        dict.__delitem__(self, key)
+        key, prev, next = self.__map.pop(key)
+        prev[2] = next
+        next[1] = prev
+
+    def __iter__(self):
+        end = self.__end
+        curr = end[2]
+        while curr is not end:
+            yield curr[0]
+            curr = curr[2]
+
+    def __reversed__(self):
+        end = self.__end
+        curr = end[1]
+        while curr is not end:
+            yield curr[0]
+            curr = curr[1]
+
+    def popitem(self, last=True):
+        if not self:
+            raise KeyError('dictionary is empty')
+        if last:
+            key = reversed(self).next()
+        else:
+            key = iter(self).next()
+        value = self.pop(key)
+        return key, value
+
+    def __reduce__(self):
+        items = [[k, self[k]] for k in self]
+        tmp = self.__map, self.__end
+        del self.__map, self.__end
+        inst_dict = vars(self).copy()
+        self.__map, self.__end = tmp
+        if inst_dict:
+            return (self.__class__, (items,), inst_dict)
+        return self.__class__, (items,)
+
+    def keys(self):
+        return list(self)
+
+    setdefault = DictMixin.setdefault
+    update = DictMixin.update
+    pop = DictMixin.pop
+    values = DictMixin.values
+    items = DictMixin.items
+    iterkeys = DictMixin.iterkeys
+    itervalues = DictMixin.itervalues
+    iteritems = DictMixin.iteritems
+
+    def __repr__(self):
+        if not self:
+            return '%s()' % (self.__class__.__name__,)
+        return '%s(%r)' % (self.__class__.__name__, self.items())
+
+    def copy(self):
+        return self.__class__(self)
+
+    @classmethod
+    def fromkeys(cls, iterable, value=None):
+        d = cls()
+        for key in iterable:
+            d[key] = value
+        return d
+
+    def __eq__(self, other):
+        if isinstance(other, OrderedDict):
+            if len(self) != len(other):
+                return False
+            for p, q in  zip(self.items(), other.items()):
+                if p != q:
+                    return False
+            return True
+        return dict.__eq__(self, other)
+
+    def __ne__(self, other):
+        return not self == other
diff --git a/lib3/Chameleon-2.9.2/src/pkg_resources.py b/lib3/Chameleon-2.9.2/src/pkg_resources.py
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/src/pkg_resources.py
@@ -0,0 +1,2838 @@
+"""Package resource API
+--------------------
+
+A resource is a logical file contained within a package, or a logical
+subdirectory thereof.  The package resource API expects resource names
+to have their path parts separated with ``/``, *not* whatever the local
+path separator is.  Do not use os.path operations to manipulate resource
+names being passed into the API.
+
+The package resource API is designed to work with normal filesystem packages,
+.egg files, and unpacked .egg files.  It can also work in a limited way with
+.zip files and with custom PEP 302 loaders that support the ``get_data()``
+method.
+"""
+
+import sys, os, zipimport, time, re, imp, types
+from urllib.parse import urlparse, urlunparse
+
+try:
+    frozenset
+except NameError:
+    from sets import ImmutableSet as frozenset
+
+# capture these to bypass sandboxing
+from os import utime
+try:
+    from os import mkdir, rename, unlink
+    WRITE_SUPPORT = True
+except ImportError:
+    # no write support, probably under GAE
+    WRITE_SUPPORT = False
+
+from os import open as os_open
+from os.path import isdir, split
+
+# This marker is used to simplify the process that checks is the
+# setuptools package was installed by the Setuptools project
+# or by the Distribute project, in case Setuptools creates
+# a distribution with the same version.
+#
+# The bootstrapping script for instance, will check if this
+# attribute is present to decide wether to reinstall the package
+_distribute = True
+
+def _bypass_ensure_directory(name, mode=0o777):
+    # Sandbox-bypassing version of ensure_directory()
+    if not WRITE_SUPPORT:
+        raise IOError('"os.mkdir" not supported on this platform.')
+    dirname, filename = split(name)
+    if dirname and filename and not isdir(dirname):
+        _bypass_ensure_directory(dirname)
+        mkdir(dirname, mode)
+
+
+_state_vars = {}
+
+def _declare_state(vartype, **kw):
+    g = globals()
+    for name, val in kw.items():
+        g[name] = val
+        _state_vars[name] = vartype
+
+def __getstate__():
+    state = {}
+    g = globals()
+    for k, v in _state_vars.items():
+        state[k] = g['_sget_'+v](g[k])
+    return state
+
+def __setstate__(state):
+    g = globals()
+    for k, v in state.items():
+        g['_sset_'+_state_vars[k]](k, g[k], v)
+    return state
+
+def _sget_dict(val):
+    return val.copy()
+
+def _sset_dict(key, ob, state):
+    ob.clear()
+    ob.update(state)
+
+def _sget_object(val):
+    return val.__getstate__()
+
+def _sset_object(key, ob, state):
+    ob.__setstate__(state)
+
+_sget_none = _sset_none = lambda *args: None
+
+
+
+def get_supported_platform():
+    """Return this platform's maximum compatible version.
+
+    distutils.util.get_platform() normally reports the minimum version
+    of Mac OS X that would be required to *use* extensions produced by
+    distutils.  But what we want when checking compatibility is to know the
+    version of Mac OS X that we are *running*.  To allow usage of packages that
+    explicitly require a newer version of Mac OS X, we must also know the
+    current version of the OS.
+
+    If this condition occurs for any other platform with a version in its
+    platform strings, this function should be extended accordingly.
+    """
+    plat = get_build_platform(); m = macosVersionString.match(plat)
+    if m is not None and sys.platform == "darwin":
+        try:
+            plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3))
+        except ValueError:
+            pass    # not Mac OS X
+    return plat
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+__all__ = [
+    # Basic resource access and distribution/entry point discovery
+    'require', 'run_script', 'get_provider',  'get_distribution',
+    'load_entry_point', 'get_entry_map', 'get_entry_info', 'iter_entry_points',
+    'resource_string', 'resource_stream', 'resource_filename',
+    'resource_listdir', 'resource_exists', 'resource_isdir',
+
+    # Environmental control
+    'declare_namespace', 'working_set', 'add_activation_listener',
+    'find_distributions', 'set_extraction_path', 'cleanup_resources',
+    'get_default_cache',
+
+    # Primary implementation classes
+    'Environment', 'WorkingSet', 'ResourceManager',
+    'Distribution', 'Requirement', 'EntryPoint',
+
+    # Exceptions
+    'ResolutionError','VersionConflict','DistributionNotFound','UnknownExtra',
+    'ExtractionError',
+
+    # Parsing functions and string utilities
+    'parse_requirements', 'parse_version', 'safe_name', 'safe_version',
+    'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections',
+    'safe_extra', 'to_filename',
+
+    # filesystem utilities
+    'ensure_directory', 'normalize_path',
+
+    # Distribution "precedence" constants
+    'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST',
+
+    # "Provider" interfaces, implementations, and registration/lookup APIs
+    'IMetadataProvider', 'IResourceProvider', 'FileMetadata',
+    'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider',
+    'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider',
+    'register_finder', 'register_namespace_handler', 'register_loader_type',
+    'fixup_namespace_packages', 'get_importer',
+
+    # Deprecated/backward compatibility only
+    'run_main', 'AvailableDistributions',
+]
+class ResolutionError(Exception):
+    """Abstract base for dependency resolution errors"""
+    def __repr__(self):
+        return self.__class__.__name__+repr(self.args)
+
+class VersionConflict(ResolutionError):
+    """An already-installed version conflicts with the requested version"""
+
+class DistributionNotFound(ResolutionError):
+    """A requested distribution was not found"""
+
+class UnknownExtra(ResolutionError):
+    """Distribution doesn't have an "extra feature" of the given name"""
+_provider_factories = {}
+
+PY_MAJOR = sys.version[:3]
+EGG_DIST    = 3
+BINARY_DIST = 2
+SOURCE_DIST = 1
+CHECKOUT_DIST = 0
+DEVELOP_DIST = -1
+
+def register_loader_type(loader_type, provider_factory):
+    """Register `provider_factory` to make providers for `loader_type`
+
+    `loader_type` is the type or class of a PEP 302 ``module.__loader__``,
+    and `provider_factory` is a function that, passed a *module* object,
+    returns an ``IResourceProvider`` for that module.
+    """
+    _provider_factories[loader_type] = provider_factory
+
+def get_provider(moduleOrReq):
+    """Return an IResourceProvider for the named module or requirement"""
+    if isinstance(moduleOrReq,Requirement):
+        return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
+    try:
+        module = sys.modules[moduleOrReq]
+    except KeyError:
+        __import__(moduleOrReq)
+        module = sys.modules[moduleOrReq]
+    loader = getattr(module, '__loader__', None)
+    return _find_adapter(_provider_factories, loader)(module)
+
+def _macosx_vers(_cache=[]):
+    if not _cache:
+        import platform
+        version = platform.mac_ver()[0]
+        # fallback for MacPorts
+        if version == '':
+            import plistlib
+            plist = '/System/Library/CoreServices/SystemVersion.plist'
+            if os.path.exists(plist):
+                if hasattr(plistlib, 'readPlist'):
+                    plist_content = plistlib.readPlist(plist)
+                    if 'ProductVersion' in plist_content:
+                        version = plist_content['ProductVersion']
+
+        _cache.append(version.split('.'))
+    return _cache[0]
+
+def _macosx_arch(machine):
+    return {'PowerPC':'ppc', 'Power_Macintosh':'ppc'}.get(machine,machine)
+
+def get_build_platform():
+    """Return this platform's string for platform-specific distributions
+
+    XXX Currently this is the same as ``distutils.util.get_platform()``, but it
+    needs some hacks for Linux and Mac OS X.
+    """
+    try:
+        from distutils.util import get_platform
+    except ImportError:
+        from sysconfig import get_platform
+
+    plat = get_platform()
+    if sys.platform == "darwin" and not plat.startswith('macosx-'):
+        try:
+            version = _macosx_vers()
+            machine = os.uname()[4].replace(" ", "_")
+            return "macosx-%d.%d-%s" % (int(version[0]), int(version[1]),
+                _macosx_arch(machine))
+        except ValueError:
+            # if someone is running a non-Mac darwin system, this will fall
+            # through to the default implementation
+            pass
+    return plat
+
+macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)")
+darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)")
+get_platform = get_build_platform   # XXX backward compat
+
+def compatible_platforms(provided,required):
+    """Can code for the `provided` platform run on the `required` platform?
+
+    Returns true if either platform is ``None``, or the platforms are equal.
+
+    XXX Needs compatibility checks for Linux and other unixy OSes.
+    """
+    if provided is None or required is None or provided==required:
+        return True     # easy case
+
+    # Mac OS X special cases
+    reqMac = macosVersionString.match(required)
+    if reqMac:
+        provMac = macosVersionString.match(provided)
+
+        # is this a Mac package?
+        if not provMac:
+            # this is backwards compatibility for packages built before
+            # setuptools 0.6. All packages built after this point will
+            # use the new macosx designation.
+            provDarwin = darwinVersionString.match(provided)
+            if provDarwin:
+                dversion = int(provDarwin.group(1))
+                macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2))
+                if dversion == 7 and macosversion >= "10.3" or \
+                    dversion == 8 and macosversion >= "10.4":
+
+                    #import warnings
+                    #warnings.warn("Mac eggs should be rebuilt to "
+                    #    "use the macosx designation instead of darwin.",
+                    #    category=DeprecationWarning)
+                    return True
+            return False    # egg isn't macosx or legacy darwin
+
+        # are they the same major version and machine type?
+        if provMac.group(1) != reqMac.group(1) or \
+            provMac.group(3) != reqMac.group(3):
+            return False
+
+
+
+        # is the required OS major update >= the provided one?
+        if int(provMac.group(2)) > int(reqMac.group(2)):
+            return False
+
+        return True
+
+    # XXX Linux and other platforms' special cases should go here
+    return False
+
+
+def run_script(dist_spec, script_name):
+    """Locate distribution `dist_spec` and run its `script_name` script"""
+    ns = sys._getframe(1).f_globals
+    name = ns['__name__']
+    ns.clear()
+    ns['__name__'] = name
+    require(dist_spec)[0].run_script(script_name, ns)
+
+run_main = run_script   # backward compatibility
+
+def get_distribution(dist):
+    """Return a current distribution object for a Requirement or string"""
+    if isinstance(dist,str): dist = Requirement.parse(dist)
+    if isinstance(dist,Requirement): dist = get_provider(dist)
+    if not isinstance(dist,Distribution):
+        raise TypeError("Expected string, Requirement, or Distribution", dist)
+    return dist
+
+def load_entry_point(dist, group, name):
+    """Return `name` entry point of `group` for `dist` or raise ImportError"""
+    return get_distribution(dist).load_entry_point(group, name)
+
+def get_entry_map(dist, group=None):
+    """Return the entry point map for `group`, or the full entry map"""
+    return get_distribution(dist).get_entry_map(group)
+
+def get_entry_info(dist, group, name):
+    """Return the EntryPoint object for `group`+`name`, or ``None``"""
+    return get_distribution(dist).get_entry_info(group, name)
+
+
+class IMetadataProvider:
+
+    def has_metadata(name):
+        """Does the package's distribution contain the named metadata?"""
+
+    def get_metadata(name):
+        """The named metadata resource as a string"""
+
+    def get_metadata_lines(name):
+        """Yield named metadata resource as list of non-blank non-comment lines
+
+       Leading and trailing whitespace is stripped from each line, and lines
+       with ``#`` as the first non-blank character are omitted."""
+
+    def metadata_isdir(name):
+        """Is the named metadata a directory?  (like ``os.path.isdir()``)"""
+
+    def metadata_listdir(name):
+        """List of metadata names in the directory (like ``os.listdir()``)"""
+
+    def run_script(script_name, namespace):
+        """Execute the named script in the supplied namespace dictionary"""
+
+
+
+
+
+
+
+
+
+
+class IResourceProvider(IMetadataProvider):
+    """An object that provides access to package resources"""
+
+    def get_resource_filename(manager, resource_name):
+        """Return a true filesystem path for `resource_name`
+
+        `manager` must be an ``IResourceManager``"""
+
+    def get_resource_stream(manager, resource_name):
+        """Return a readable file-like object for `resource_name`
+
+        `manager` must be an ``IResourceManager``"""
+
+    def get_resource_string(manager, resource_name):
+        """Return a string containing the contents of `resource_name`
+
+        `manager` must be an ``IResourceManager``"""
+
+    def has_resource(resource_name):
+        """Does the package contain the named resource?"""
+
+    def resource_isdir(resource_name):
+        """Is the named resource a directory?  (like ``os.path.isdir()``)"""
+
+    def resource_listdir(resource_name):
+        """List of resource names in the directory (like ``os.listdir()``)"""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class WorkingSet(object):
+    """A collection of active distributions on sys.path (or a similar list)"""
+
+    def __init__(self, entries=None):
+        """Create working set from list of path entries (default=sys.path)"""
+        self.entries = []
+        self.entry_keys = {}
+        self.by_key = {}
+        self.callbacks = []
+
+        if entries is None:
+            entries = sys.path
+
+        for entry in entries:
+            self.add_entry(entry)
+
+
+    def add_entry(self, entry):
+        """Add a path item to ``.entries``, finding any distributions on it
+
+        ``find_distributions(entry,True)`` is used to find distributions
+        corresponding to the path entry, and they are added.  `entry` is
+        always appended to ``.entries``, even if it is already present.
+        (This is because ``sys.path`` can contain the same value more than
+        once, and the ``.entries`` of the ``sys.path`` WorkingSet should always
+        equal ``sys.path``.)
+        """
+        self.entry_keys.setdefault(entry, [])
+        self.entries.append(entry)
+        for dist in find_distributions(entry, True):
+            self.add(dist, entry, False)
+
+
+    def __contains__(self,dist):
+        """True if `dist` is the active distribution for its project"""
+        return self.by_key.get(dist.key) == dist
+
+
+
+
+
+    def find(self, req):
+        """Find a distribution matching requirement `req`
+
+        If there is an active distribution for the requested project, this
+        returns it as long as it meets the version requirement specified by
+        `req`.  But, if there is an active distribution for the project and it
+        does *not* meet the `req` requirement, ``VersionConflict`` is raised.
+        If there is no active distribution for the requested project, ``None``
+        is returned.
+        """
+        dist = self.by_key.get(req.key)
+        if dist is not None and dist not in req:
+            raise VersionConflict(dist,req)     # XXX add more info
+        else:
+            return dist
+
+    def iter_entry_points(self, group, name=None):
+        """Yield entry point objects from `group` matching `name`
+
+        If `name` is None, yields all entry points in `group` from all
+        distributions in the working set, otherwise only ones matching
+        both `group` and `name` are yielded (in distribution order).
+        """
+        for dist in self:
+            entries = dist.get_entry_map(group)
+            if name is None:
+                for ep in list(entries.values()):
+                    yield ep
+            elif name in entries:
+                yield entries[name]
+
+    def run_script(self, requires, script_name):
+        """Locate distribution for `requires` and run `script_name` script"""
+        ns = sys._getframe(1).f_globals
+        name = ns['__name__']
+        ns.clear()
+        ns['__name__'] = name
+        self.require(requires)[0].run_script(script_name, ns)
+
+
+
+    def __iter__(self):
+        """Yield distributions for non-duplicate projects in the working set
+
+        The yield order is the order in which the items' path entries were
+        added to the working set.
+        """
+        seen = {}
+        for item in self.entries:
+            if item not in self.entry_keys:
+                # workaround a cache issue
+                continue
+
+            for key in self.entry_keys[item]:
+                if key not in seen:
+                    seen[key]=1
+                    yield self.by_key[key]
+
+    def add(self, dist, entry=None, insert=True):
+        """Add `dist` to working set, associated with `entry`
+
+        If `entry` is unspecified, it defaults to the ``.location`` of `dist`.
+        On exit from this routine, `entry` is added to the end of the working
+        set's ``.entries`` (if it wasn't already present).
+
+        `dist` is only added to the working set if it's for a project that
+        doesn't already have a distribution in the set.  If it's added, any
+        callbacks registered with the ``subscribe()`` method will be called.
+        """
+        if insert:
+            dist.insert_on(self.entries, entry)
+
+        if entry is None:
+            entry = dist.location
+        keys = self.entry_keys.setdefault(entry,[])
+        keys2 = self.entry_keys.setdefault(dist.location,[])
+        if dist.key in self.by_key:
+            return      # ignore hidden distros
+
+        self.by_key[dist.key] = dist
+        if dist.key not in keys:
+            keys.append(dist.key)
+        if dist.key not in keys2:
+            keys2.append(dist.key)
+        self._added_new(dist)
+
+    def resolve(self, requirements, env=None, installer=None, replacement=True):
+        """List all distributions needed to (recursively) meet `requirements`
+
+        `requirements` must be a sequence of ``Requirement`` objects.  `env`,
+        if supplied, should be an ``Environment`` instance.  If
+        not supplied, it defaults to all distributions available within any
+        entry or distribution in the working set.  `installer`, if supplied,
+        will be invoked with each requirement that cannot be met by an
+        already-installed distribution; it should return a ``Distribution`` or
+        ``None``.
+        """
+
+        requirements = list(requirements)[::-1]  # set up the stack
+        processed = {}  # set of processed requirements
+        best = {}  # key -> dist
+        to_activate = []
+
+        while requirements:
+            req = requirements.pop(0)   # process dependencies breadth-first
+            if _override_setuptools(req) and replacement:
+                req = Requirement.parse('distribute')
+
+            if req in processed:
+                # Ignore cyclic or redundant dependencies
+                continue
+            dist = best.get(req.key)
+            if dist is None:
+                # Find the best distribution and add it to the map
+                dist = self.by_key.get(req.key)
+                if dist is None:
+                    if env is None:
+                        env = Environment(self.entries)
+                    dist = best[req.key] = env.best_match(req, self, installer)
+                    if dist is None:
+                        #msg = ("The '%s' distribution was not found on this "
+                        #       "system, and is required by this application.")
+                        #raise DistributionNotFound(msg % req)
+
+                        # unfortunately, zc.buildout uses a str(err)
+                        # to get the name of the distribution here..
+                        raise DistributionNotFound(req)
+                to_activate.append(dist)
+            if dist not in req:
+                # Oops, the "best" so far conflicts with a dependency
+                raise VersionConflict(dist,req) # XXX put more info here
+            requirements.extend(dist.requires(req.extras)[::-1])
+            processed[req] = True
+
+        return to_activate    # return list of distros to activate
+
+    def find_plugins(self,
+        plugin_env, full_env=None, installer=None, fallback=True
+    ):
+        """Find all activatable distributions in `plugin_env`
+
+        Example usage::
+
+            distributions, errors = working_set.find_plugins(
+                Environment(plugin_dirlist)
+            )
+            map(working_set.add, distributions)  # add plugins+libs to sys.path
+            print 'Could not load', errors        # display errors
+
+        The `plugin_env` should be an ``Environment`` instance that contains
+        only distributions that are in the project's "plugin directory" or
+        directories. The `full_env`, if supplied, should be an ``Environment``
+        contains all currently-available distributions.  If `full_env` is not
+        supplied, one is created automatically from the ``WorkingSet`` this
+        method is called on, which will typically mean that every directory on
+        ``sys.path`` will be scanned for distributions.
+
+        `installer` is a standard installer callback as used by the
+        ``resolve()`` method. The `fallback` flag indicates whether we should
+        attempt to resolve older versions of a plugin if the newest version
+        cannot be resolved.
+
+        This method returns a 2-tuple: (`distributions`, `error_info`), where
+        `distributions` is a list of the distributions found in `plugin_env`
+        that were loadable, along with any other distributions that are needed
+        to resolve their dependencies.  `error_info` is a dictionary mapping
+        unloadable plugin distributions to an exception instance describing the
+        error that occurred. Usually this will be a ``DistributionNotFound`` or
+        ``VersionConflict`` instance.
+        """
+
+        plugin_projects = list(plugin_env)
+        plugin_projects.sort()  # scan project names in alphabetic order
+
+        error_info = {}
+        distributions = {}
+
+        if full_env is None:
+            env = Environment(self.entries)
+            env += plugin_env
+        else:
+            env = full_env + plugin_env
+
+        shadow_set = self.__class__([])
+        list(map(shadow_set.add, self))   # put all our entries in shadow_set
+
+        for project_name in plugin_projects:
+
+            for dist in plugin_env[project_name]:
+
+                req = [dist.as_requirement()]
+
+                try:
+                    resolvees = shadow_set.resolve(req, env, installer)
+
+                except ResolutionError as v:
+                    error_info[dist] = v    # save error info
+                    if fallback:
+                        continue    # try the next older version of project
+                    else:
+                        break       # give up on this project, keep going
+
+                else:
+                    list(map(shadow_set.add, resolvees))
+                    distributions.update(dict.fromkeys(resolvees))
+
+                    # success, no need to try any more versions of this project
+                    break
+
+        distributions = list(distributions)
+        distributions.sort()
+
+        return distributions, error_info
+
+
+
+
+
+    def require(self, *requirements):
+        """Ensure that distributions matching `requirements` are activated
+
+        `requirements` must be a string or a (possibly-nested) sequence
+        thereof, specifying the distributions and versions required.  The
+        return value is a sequence of the distributions that needed to be
+        activated to fulfill the requirements; all relevant distributions are
+        included, even if they were already activated in this working set.
+        """
+
+        needed = self.resolve(parse_requirements(requirements))
+
+        for dist in needed:
+            self.add(dist)
+
+        return needed
+
+
+    def subscribe(self, callback):
+        """Invoke `callback` for all distributions (including existing ones)"""
+        if callback in self.callbacks:
+            return
+        self.callbacks.append(callback)
+        for dist in self:
+            callback(dist)
+
+
+    def _added_new(self, dist):
+        for callback in self.callbacks:
+            callback(dist)
+
+    def __getstate__(self):
+        return (self.entries[:], self.entry_keys.copy(), self.by_key.copy(),
+                self.callbacks[:])
+
+    def __setstate__(self, xxx_todo_changeme):
+        (entries, keys, by_key, callbacks) = xxx_todo_changeme
+        self.entries = entries[:]
+        self.entry_keys = keys.copy()
+        self.by_key = by_key.copy()
+        self.callbacks = callbacks[:]
+
+
+
+
+class Environment(object):
+    """Searchable snapshot of distributions on a search path"""
+
+    def __init__(self, search_path=None, platform=get_supported_platform(), python=PY_MAJOR):
+        """Snapshot distributions available on a search path
+
+        Any distributions found on `search_path` are added to the environment.
+        `search_path` should be a sequence of ``sys.path`` items.  If not
+        supplied, ``sys.path`` is used.
+
+        `platform` is an optional string specifying the name of the platform
+        that platform-specific distributions must be compatible with.  If
+        unspecified, it defaults to the current platform.  `python` is an
+        optional string naming the desired version of Python (e.g. ``'2.4'``);
+        it defaults to the current version.
+
+        You may explicitly set `platform` (and/or `python`) to ``None`` if you
+        wish to map *all* distributions, not just those compatible with the
+        running platform or Python version.
+        """
+        self._distmap = {}
+        self._cache = {}
+        self.platform = platform
+        self.python = python
+        self.scan(search_path)
+
+    def can_add(self, dist):
+        """Is distribution `dist` acceptable for this environment?
+
+        The distribution must match the platform and python version
+        requirements specified when this environment was created, or False
+        is returned.
+        """
+        return (self.python is None or dist.py_version is None
+            or dist.py_version==self.python) \
+           and compatible_platforms(dist.platform,self.platform)
+
+    def remove(self, dist):
+        """Remove `dist` from the environment"""
+        self._distmap[dist.key].remove(dist)
+
+    def scan(self, search_path=None):
+        """Scan `search_path` for distributions usable in this environment
+
+        Any distributions found are added to the environment.
+        `search_path` should be a sequence of ``sys.path`` items.  If not
+        supplied, ``sys.path`` is used.  Only distributions conforming to
+        the platform/python version defined at initialization are added.
+        """
+        if search_path is None:
+            search_path = sys.path
+
+        for item in search_path:
+            for dist in find_distributions(item):
+                self.add(dist)
+
+    def __getitem__(self,project_name):
+        """Return a newest-to-oldest list of distributions for `project_name`
+        """
+        try:
+            return self._cache[project_name]
+        except KeyError:
+            project_name = project_name.lower()
+            if project_name not in self._distmap:
+                return []
+
+        if project_name not in self._cache:
+            dists = self._cache[project_name] = self._distmap[project_name]
+            _sort_dists(dists)
+
+        return self._cache[project_name]
+
+    def add(self,dist):
+        """Add `dist` if we ``can_add()`` it and it isn't already added"""
+        if self.can_add(dist) and dist.has_version():
+            dists = self._distmap.setdefault(dist.key,[])
+            if dist not in dists:
+                dists.append(dist)
+                if dist.key in self._cache:
+                    _sort_dists(self._cache[dist.key])
+
+
+    def best_match(self, req, working_set, installer=None):
+        """Find distribution best matching `req` and usable on `working_set`
+
+        This calls the ``find(req)`` method of the `working_set` to see if a
+        suitable distribution is already active.  (This may raise
+        ``VersionConflict`` if an unsuitable version of the project is already
+        active in the specified `working_set`.)  If a suitable distribution
+        isn't active, this method returns the newest distribution in the
+        environment that meets the ``Requirement`` in `req`.  If no suitable
+        distribution is found, and `installer` is supplied, then the result of
+        calling the environment's ``obtain(req, installer)`` method will be
+        returned.
+        """
+        dist = working_set.find(req)
+        if dist is not None:
+            return dist
+        for dist in self[req.key]:
+            if dist in req:
+                return dist
+        return self.obtain(req, installer) # try and download/install
+
+    def obtain(self, requirement, installer=None):
+        """Obtain a distribution matching `requirement` (e.g. via download)
+
+        Obtain a distro that matches requirement (e.g. via download).  In the
+        base ``Environment`` class, this routine just returns
+        ``installer(requirement)``, unless `installer` is None, in which case
+        None is returned instead.  This method is a hook that allows subclasses
+        to attempt other ways of obtaining a distribution before falling back
+        to the `installer` argument."""
+        if installer is not None:
+            return installer(requirement)
+
+    def __iter__(self):
+        """Yield the unique project names of the available distributions"""
+        for key in list(self._distmap.keys()):
+            if self[key]: yield key
+
+
+
+
+    def __iadd__(self, other):
+        """In-place addition of a distribution or environment"""
+        if isinstance(other,Distribution):
+            self.add(other)
+        elif isinstance(other,Environment):
+            for project in other:
+                for dist in other[project]:
+                    self.add(dist)
+        else:
+            raise TypeError("Can't add %r to environment" % (other,))
+        return self
+
+    def __add__(self, other):
+        """Add an environment or distribution to an environment"""
+        new = self.__class__([], platform=None, python=None)
+        for env in self, other:
+            new += env
+        return new
+
+
+AvailableDistributions = Environment    # XXX backward compatibility
+
+
+class ExtractionError(RuntimeError):
+    """An error occurred extracting a resource
+
+    The following attributes are available from instances of this exception:
+
+    manager
+        The resource manager that raised this exception
+
+    cache_path
+        The base directory for resource extraction
+
+    original_error
+        The exception instance that caused extraction to fail
+    """
+
+
+
+
+class ResourceManager:
+    """Manage resource extraction and packages"""
+    extraction_path = None
+
+    def __init__(self):
+        self.cached_files = {}
+
+    def resource_exists(self, package_or_requirement, resource_name):
+        """Does the named resource exist?"""
+        return get_provider(package_or_requirement).has_resource(resource_name)
+
+    def resource_isdir(self, package_or_requirement, resource_name):
+        """Is the named resource an existing directory?"""
+        return get_provider(package_or_requirement).resource_isdir(
+            resource_name
+        )
+
+    def resource_filename(self, package_or_requirement, resource_name):
+        """Return a true filesystem path for specified resource"""
+        return get_provider(package_or_requirement).get_resource_filename(
+            self, resource_name
+        )
+
+    def resource_stream(self, package_or_requirement, resource_name):
+        """Return a readable file-like object for specified resource"""
+        return get_provider(package_or_requirement).get_resource_stream(
+            self, resource_name
+        )
+
+    def resource_string(self, package_or_requirement, resource_name):
+        """Return specified resource as a string"""
+        return get_provider(package_or_requirement).get_resource_string(
+            self, resource_name
+        )
+
+    def resource_listdir(self, package_or_requirement, resource_name):
+        """List the contents of the named resource directory"""
+        return get_provider(package_or_requirement).resource_listdir(
+            resource_name
+        )
+
+    def extraction_error(self):
+        """Give an error message for problems extracting file(s)"""
+
+        old_exc = sys.exc_info()[1]
+        cache_path = self.extraction_path or get_default_cache()
+
+        err = ExtractionError("""Can't extract file(s) to egg cache
+
+The following error occurred while trying to extract file(s) to the Python egg
+cache:
+
+  %s
+
+The Python egg cache directory is currently set to:
+
+  %s
+
+Perhaps your account does not have write access to this directory?  You can
+change the cache directory by setting the PYTHON_EGG_CACHE environment
+variable to point to an accessible directory.
+"""         % (old_exc, cache_path)
+        )
+        err.manager        = self
+        err.cache_path     = cache_path
+        err.original_error = old_exc
+        raise err
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    def get_cache_path(self, archive_name, names=()):
+        """Return absolute location in cache for `archive_name` and `names`
+
+        The parent directory of the resulting path will be created if it does
+        not already exist.  `archive_name` should be the base filename of the
+        enclosing egg (which may not be the name of the enclosing zipfile!),
+        including its ".egg" extension.  `names`, if provided, should be a
+        sequence of path name parts "under" the egg's extraction location.
+
+        This method should only be called by resource providers that need to
+        obtain an extraction location, and only for names they intend to
+        extract, as it tracks the generated names for possible cleanup later.
+        """
+        extract_path = self.extraction_path or get_default_cache()
+        target_path = os.path.join(extract_path, archive_name+'-tmp', *names)
+        try:
+            _bypass_ensure_directory(target_path)
+        except:
+            self.extraction_error()
+
+        self.cached_files[target_path] = 1
+        return target_path
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    def postprocess(self, tempname, filename):
+        """Perform any platform-specific postprocessing of `tempname`
+
+        This is where Mac header rewrites should be done; other platforms don't
+        have anything special they should do.
+
+        Resource providers should call this method ONLY after successfully
+        extracting a compressed resource.  They must NOT call it on resources
+        that are already in the filesystem.
+
+        `tempname` is the current (temporary) name of the file, and `filename`
+        is the name it will be renamed to by the caller after this routine
+        returns.
+        """
+
+        if os.name == 'posix':
+            # Make the resource executable
+            mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777
+            os.chmod(tempname, mode)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    def set_extraction_path(self, path):
+        """Set the base path where resources will be extracted to, if needed.
+
+        If you do not call this routine before any extractions take place, the
+        path defaults to the return value of ``get_default_cache()``.  (Which
+        is based on the ``PYTHON_EGG_CACHE`` environment variable, with various
+        platform-specific fallbacks.  See that routine's documentation for more
+        details.)
+
+        Resources are extracted to subdirectories of this path based upon
+        information given by the ``IResourceProvider``.  You may set this to a
+        temporary directory, but then you must call ``cleanup_resources()`` to
+        delete the extracted files when done.  There is no guarantee that
+        ``cleanup_resources()`` will be able to remove all extracted files.
+
+        (Note: you may not change the extraction path for a given resource
+        manager once resources have been extracted, unless you first call
+        ``cleanup_resources()``.)
+        """
+        if self.cached_files:
+            raise ValueError(
+                "Can't change extraction path, files already extracted"
+            )
+
+        self.extraction_path = path
+
+    def cleanup_resources(self, force=False):
+        """
+        Delete all extracted resource files and directories, returning a list
+        of the file and directory names that could not be successfully removed.
+        This function does not have any concurrency protection, so it should
+        generally only be called when the extraction path is a temporary
+        directory exclusive to a single process.  This method is not
+        automatically called; you must call it explicitly or register it as an
+        ``atexit`` function if you wish to ensure cleanup of a temporary
+        directory used for extractions.
+        """
+        # XXX
+
+
+
+def get_default_cache():
+    """Determine the default cache location
+
+    This returns the ``PYTHON_EGG_CACHE`` environment variable, if set.
+    Otherwise, on Windows, it returns a "Python-Eggs" subdirectory of the
+    "Application Data" directory.  On all other systems, it's "~/.python-eggs".
+    """
+    try:
+        return os.environ['PYTHON_EGG_CACHE']
+    except KeyError:
+        pass
+
+    if os.name!='nt':
+        return os.path.expanduser('~/.python-eggs')
+
+    app_data = 'Application Data'   # XXX this may be locale-specific!
+    app_homes = [
+        (('APPDATA',), None),       # best option, should be locale-safe
+        (('USERPROFILE',), app_data),
+        (('HOMEDRIVE','HOMEPATH'), app_data),
+        (('HOMEPATH',), app_data),
+        (('HOME',), None),
+        (('WINDIR',), app_data),    # 95/98/ME
+    ]
+
+    for keys, subdir in app_homes:
+        dirname = ''
+        for key in keys:
+            if key in os.environ:
+                dirname = os.path.join(dirname, os.environ[key])
+            else:
+                break
+        else:
+            if subdir:
+                dirname = os.path.join(dirname,subdir)
+            return os.path.join(dirname, 'Python-Eggs')
+    else:
+        raise RuntimeError(
+            "Please set the PYTHON_EGG_CACHE enviroment variable"
+        )
+
+def safe_name(name):
+    """Convert an arbitrary string to a standard distribution name
+
+    Any runs of non-alphanumeric/. characters are replaced with a single '-'.
+    """
+    return re.sub('[^A-Za-z0-9.]+', '-', name)
+
+
+def safe_version(version):
+    """Convert an arbitrary string to a standard version string
+
+    Spaces become dots, and all other non-alphanumeric characters become
+    dashes, with runs of multiple dashes condensed to a single dash.
+    """
+    version = version.replace(' ','.')
+    return re.sub('[^A-Za-z0-9.]+', '-', version)
+
+
+def safe_extra(extra):
+    """Convert an arbitrary string to a standard 'extra' name
+
+    Any runs of non-alphanumeric characters are replaced with a single '_',
+    and the result is always lowercased.
+    """
+    return re.sub('[^A-Za-z0-9.]+', '_', extra).lower()
+
+
+def to_filename(name):
+    """Convert a project or version name to its filename-escaped form
+
+    Any '-' characters are currently replaced with '_'.
+    """
+    return name.replace('-','_')
+
+
+
+
+
+
+
+
+class NullProvider:
+    """Try to implement resources and metadata for arbitrary PEP 302 loaders"""
+
+    egg_name = None
+    egg_info = None
+    loader = None
+
+    def __init__(self, module):
+        self.loader = getattr(module, '__loader__', None)
+        self.module_path = os.path.dirname(getattr(module, '__file__', ''))
+
+    def get_resource_filename(self, manager, resource_name):
+        return self._fn(self.module_path, resource_name)
+
+    def get_resource_stream(self, manager, resource_name):
+        return StringIO(self.get_resource_string(manager, resource_name))
+
+    def get_resource_string(self, manager, resource_name):
+        return self._get(self._fn(self.module_path, resource_name))
+
+    def has_resource(self, resource_name):
+        return self._has(self._fn(self.module_path, resource_name))
+
+    def has_metadata(self, name):
+        return self.egg_info and self._has(self._fn(self.egg_info,name))
+
+    if sys.version_info <= (3,):
+        def get_metadata(self, name):
+            if not self.egg_info:
+                return ""
+            return self._get(self._fn(self.egg_info,name))
+    else:
+        def get_metadata(self, name):
+            if not self.egg_info:
+                return ""
+            return self._get(self._fn(self.egg_info,name)).decode("utf-8")
+
+    def get_metadata_lines(self, name):
+        return yield_lines(self.get_metadata(name))
+
+    def resource_isdir(self,resource_name):
+        return self._isdir(self._fn(self.module_path, resource_name))
+
+    def metadata_isdir(self,name):
+        return self.egg_info and self._isdir(self._fn(self.egg_info,name))
+
+
+    def resource_listdir(self,resource_name):
+        return self._listdir(self._fn(self.module_path,resource_name))
+
+    def metadata_listdir(self,name):
+        if self.egg_info:
+            return self._listdir(self._fn(self.egg_info,name))
+        return []
+
+    def run_script(self,script_name,namespace):
+        script = 'scripts/'+script_name
+        if not self.has_metadata(script):
+            raise ResolutionError("No script named %r" % script_name)
+        script_text = self.get_metadata(script).replace('\r\n','\n')
+        script_text = script_text.replace('\r','\n')
+        script_filename = self._fn(self.egg_info,script)
+        namespace['__file__'] = script_filename
+        if os.path.exists(script_filename):
+            exec(compile(open(script_filename).read(), script_filename, 'exec'), namespace, namespace)
+        else:
+            from linecache import cache
+            cache[script_filename] = (
+                len(script_text), 0, script_text.split('\n'), script_filename
+            )
+            script_code = compile(script_text,script_filename,'exec')
+            exec(script_code, namespace, namespace)
+
+    def _has(self, path):
+        raise NotImplementedError(
+            "Can't perform this operation for unregistered loader type"
+        )
+
+    def _isdir(self, path):
+        raise NotImplementedError(
+            "Can't perform this operation for unregistered loader type"
+        )
+
+    def _listdir(self, path):
+        raise NotImplementedError(
+            "Can't perform this operation for unregistered loader type"
+        )
+
+    def _fn(self, base, resource_name):
+        if resource_name:
+            return os.path.join(base, *resource_name.split('/'))
+        return base
+
+    def _get(self, path):
+        if hasattr(self.loader, 'get_data'):
+            return self.loader.get_data(path)
+        raise NotImplementedError(
+            "Can't perform this operation for loaders without 'get_data()'"
+        )
+
+register_loader_type(object, NullProvider)
+
+
+class EggProvider(NullProvider):
+    """Provider based on a virtual filesystem"""
+
+    def __init__(self,module):
+        NullProvider.__init__(self,module)
+        self._setup_prefix()
+
+    def _setup_prefix(self):
+        # we assume here that our metadata may be nested inside a "basket"
+        # of multiple eggs; that's why we use module_path instead of .archive
+        path = self.module_path
+        old = None
+        while path!=old:
+            if path.lower().endswith('.egg'):
+                self.egg_name = os.path.basename(path)
+                self.egg_info = os.path.join(path, 'EGG-INFO')
+                self.egg_root = path
+                break
+            old = path
+            path, base = os.path.split(path)
+
+
+
+
+
+
+class DefaultProvider(EggProvider):
+    """Provides access to package resources in the filesystem"""
+
+    def _has(self, path):
+        return os.path.exists(path)
+
+    def _isdir(self,path):
+        return os.path.isdir(path)
+
+    def _listdir(self,path):
+        return os.listdir(path)
+
+    def get_resource_stream(self, manager, resource_name):
+        return open(self._fn(self.module_path, resource_name), 'rb')
+
+    def _get(self, path):
+        stream = open(path, 'rb')
+        try:
+            return stream.read()
+        finally:
+            stream.close()
+
+register_loader_type(type(None), DefaultProvider)
+
+try:
+    # CPython >=3.3
+    import _frozen_importlib
+except ImportError:
+    pass
+else:
+    register_loader_type(_frozen_importlib.SourceFileLoader, DefaultProvider)
+
+
+class EmptyProvider(NullProvider):
+    """Provider that returns nothing for all requests"""
+
+    _isdir = _has = lambda self,path: False
+    _get          = lambda self,path: ''
+    _listdir      = lambda self,path: []
+    module_path   = None
+
+    def __init__(self):
+        pass
+
+empty_provider = EmptyProvider()
+
+
+
+
+class ZipProvider(EggProvider):
+    """Resource support for zips and eggs"""
+
+    eagers = None
+
+    def __init__(self, module):
+        EggProvider.__init__(self,module)
+        self.zipinfo = zipimport._zip_directory_cache[self.loader.archive]
+        self.zip_pre = self.loader.archive+os.sep
+
+    def _zipinfo_name(self, fspath):
+        # Convert a virtual filename (full path to file) into a zipfile subpath
+        # usable with the zipimport directory cache for our target archive
+        if fspath.startswith(self.zip_pre):
+            return fspath[len(self.zip_pre):]
+        raise AssertionError(
+            "%s is not a subpath of %s" % (fspath,self.zip_pre)
+        )
+
+    def _parts(self,zip_path):
+        # Convert a zipfile subpath into an egg-relative path part list
+        fspath = self.zip_pre+zip_path  # pseudo-fs path
+        if fspath.startswith(self.egg_root+os.sep):
+            return fspath[len(self.egg_root)+1:].split(os.sep)
+        raise AssertionError(
+            "%s is not a subpath of %s" % (fspath,self.egg_root)
+        )
+
+    def get_resource_filename(self, manager, resource_name):
+        if not self.egg_name:
+            raise NotImplementedError(
+                "resource_filename() only supported for .egg, not .zip"
+            )
+        # no need to lock for extraction, since we use temp names
+        zip_path = self._resource_to_zip(resource_name)
+        eagers = self._get_eager_resources()
+        if '/'.join(self._parts(zip_path)) in eagers:
+            for name in eagers:
+                self._extract_resource(manager, self._eager_to_zip(name))
+        return self._extract_resource(manager, zip_path)
+
+    def _extract_resource(self, manager, zip_path):
+
+        if zip_path in self._index():
+            for name in self._index()[zip_path]:
+                last = self._extract_resource(
+                    manager, os.path.join(zip_path, name)
+                )
+            return os.path.dirname(last)  # return the extracted directory name
+
+        zip_stat = self.zipinfo[zip_path]
+        t,d,size = zip_stat[5], zip_stat[6], zip_stat[3]
+        date_time = (
+            (d>>9)+1980, (d>>5)&0xF, d&0x1F,                      # ymd
+            (t&0xFFFF)>>11, (t>>5)&0x3F, (t&0x1F) * 2, 0, 0, -1   # hms, etc.
+        )
+        timestamp = time.mktime(date_time)
+
+        try:
+            if not WRITE_SUPPORT:
+                raise IOError('"os.rename" and "os.unlink" are not supported '
+                              'on this platform')
+
+            real_path = manager.get_cache_path(
+                self.egg_name, self._parts(zip_path)
+            )
+
+            if os.path.isfile(real_path):
+                stat = os.stat(real_path)
+                if stat.st_size==size and stat.st_mtime==timestamp:
+                    # size and stamp match, don't bother extracting
+                    return real_path
+
+            outf, tmpnam = _mkstemp(".$extract", dir=os.path.dirname(real_path))
+            os.write(outf, self.loader.get_data(zip_path))
+            os.close(outf)
+            utime(tmpnam, (timestamp,timestamp))
+            manager.postprocess(tmpnam, real_path)
+
+            try:
+                rename(tmpnam, real_path)
+
+            except os.error:
+                if os.path.isfile(real_path):
+                    stat = os.stat(real_path)
+
+                    if stat.st_size==size and stat.st_mtime==timestamp:
+                        # size and stamp match, somebody did it just ahead of
+                        # us, so we're done
+                        return real_path
+                    elif os.name=='nt':     # Windows, del old file and retry
+                        unlink(real_path)
+                        rename(tmpnam, real_path)
+                        return real_path
+                raise
+
+        except os.error:
+            manager.extraction_error()  # report a user-friendly error
+
+        return real_path
+
+    def _get_eager_resources(self):
+        if self.eagers is None:
+            eagers = []
+            for name in ('native_libs.txt', 'eager_resources.txt'):
+                if self.has_metadata(name):
+                    eagers.extend(self.get_metadata_lines(name))
+            self.eagers = eagers
+        return self.eagers
+
+    def _index(self):
+        try:
+            return self._dirindex
+        except AttributeError:
+            ind = {}
+            for path in self.zipinfo:
+                parts = path.split(os.sep)
+                while parts:
+                    parent = os.sep.join(parts[:-1])
+                    if parent in ind:
+                        ind[parent].append(parts[-1])
+                        break
+                    else:
+                        ind[parent] = [parts.pop()]
+            self._dirindex = ind
+            return ind
+
+    def _has(self, fspath):
+        zip_path = self._zipinfo_name(fspath)
+        return zip_path in self.zipinfo or zip_path in self._index()
+
+    def _isdir(self,fspath):
+        return self._zipinfo_name(fspath) in self._index()
+
+    def _listdir(self,fspath):
+        return list(self._index().get(self._zipinfo_name(fspath), ()))
+
+    def _eager_to_zip(self,resource_name):
+        return self._zipinfo_name(self._fn(self.egg_root,resource_name))
+
+    def _resource_to_zip(self,resource_name):
+        return self._zipinfo_name(self._fn(self.module_path,resource_name))
+
+register_loader_type(zipimport.zipimporter, ZipProvider)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class FileMetadata(EmptyProvider):
+    """Metadata handler for standalone PKG-INFO files
+
+    Usage::
+
+        metadata = FileMetadata("/path/to/PKG-INFO")
+
+    This provider rejects all data and metadata requests except for PKG-INFO,
+    which is treated as existing, and will be the contents of the file at
+    the provided location.
+    """
+
+    def __init__(self,path):
+        self.path = path
+
+    def has_metadata(self,name):
+        return name=='PKG-INFO'
+
+    def get_metadata(self,name):
+        if name=='PKG-INFO':
+            f = open(self.path,'rU')
+            metadata = f.read()
+            f.close()
+            return metadata
+        raise KeyError("No metadata except PKG-INFO is available")
+
+    def get_metadata_lines(self,name):
+        return yield_lines(self.get_metadata(name))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class PathMetadata(DefaultProvider):
+    """Metadata provider for egg directories
+
+    Usage::
+
+        # Development eggs:
+
+        egg_info = "/path/to/PackageName.egg-info"
+        base_dir = os.path.dirname(egg_info)
+        metadata = PathMetadata(base_dir, egg_info)
+        dist_name = os.path.splitext(os.path.basename(egg_info))[0]
+        dist = Distribution(basedir,project_name=dist_name,metadata=metadata)
+
+        # Unpacked egg directories:
+
+        egg_path = "/path/to/PackageName-ver-pyver-etc.egg"
+        metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO'))
+        dist = Distribution.from_filename(egg_path, metadata=metadata)
+    """
+
+    def __init__(self, path, egg_info):
+        self.module_path = path
+        self.egg_info = egg_info
+
+
+class EggMetadata(ZipProvider):
+    """Metadata provider for .egg files"""
+
+    def __init__(self, importer):
+        """Create a metadata provider from a zipimporter"""
+
+        self.zipinfo = zipimport._zip_directory_cache[importer.archive]
+        self.zip_pre = importer.archive+os.sep
+        self.loader = importer
+        if importer.prefix:
+            self.module_path = os.path.join(importer.archive, importer.prefix)
+        else:
+            self.module_path = importer.archive
+        self._setup_prefix()
+
+
+class ImpWrapper:
+    """PEP 302 Importer that wraps Python's "normal" import algorithm"""
+
+    def __init__(self, path=None):
+        self.path = path
+
+    def find_module(self, fullname, path=None):
+        subname = fullname.split(".")[-1]
+        if subname != fullname and self.path is None:
+            return None
+        if self.path is None:
+            path = None
+        else:
+            path = [self.path]
+        try:
+            file, filename, etc = imp.find_module(subname, path)
+        except ImportError:
+            return None
+        return ImpLoader(file, filename, etc)
+
+
+class ImpLoader:
+    """PEP 302 Loader that wraps Python's "normal" import algorithm"""
+
+    def __init__(self, file, filename, etc):
+        self.file = file
+        self.filename = filename
+        self.etc = etc
+
+    def load_module(self, fullname):
+        try:
+            mod = imp.load_module(fullname, self.file, self.filename, self.etc)
+        finally:
+            if self.file: self.file.close()
+        # Note: we don't set __loader__ because we want the module to look
+        # normal; i.e. this is just a wrapper for standard import machinery
+        return mod
+
+
+
+
+def get_importer(path_item):
+    """Retrieve a PEP 302 "importer" for the given path item
+
+    If there is no importer, this returns a wrapper around the builtin import
+    machinery.  The returned importer is only cached if it was created by a
+    path hook.
+    """
+    try:
+        importer = sys.path_importer_cache[path_item]
+    except KeyError:
+        for hook in sys.path_hooks:
+            try:
+                importer = hook(path_item)
+            except ImportError:
+                pass
+            else:
+                break
+        else:
+            importer = None
+
+    sys.path_importer_cache.setdefault(path_item,importer)
+    if importer is None:
+        try:
+            importer = ImpWrapper(path_item)
+        except ImportError:
+            pass
+    return importer
+
+try:
+    from pkgutil import get_importer, ImpImporter
+except ImportError:
+    pass    # Python 2.3 or 2.4, use our own implementation
+else:
+    ImpWrapper = ImpImporter    # Python 2.5, use pkgutil's implementation
+    del ImpLoader, ImpImporter
+
+
+
+
+
+
+_declare_state('dict', _distribution_finders = {})
+
+def register_finder(importer_type, distribution_finder):
+    """Register `distribution_finder` to find distributions in sys.path items
+
+    `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item
+    handler), and `distribution_finder` is a callable that, passed a path
+    item and the importer instance, yields ``Distribution`` instances found on
+    that path item.  See ``pkg_resources.find_on_path`` for an example."""
+    _distribution_finders[importer_type] = distribution_finder
+
+
+def find_distributions(path_item, only=False):
+    """Yield distributions accessible via `path_item`"""
+    importer = get_importer(path_item)
+    finder = _find_adapter(_distribution_finders, importer)
+    return finder(importer, path_item, only)
+
+def find_in_zip(importer, path_item, only=False):
+    metadata = EggMetadata(importer)
+    if metadata.has_metadata('PKG-INFO'):
+        yield Distribution.from_filename(path_item, metadata=metadata)
+    if only:
+        return  # don't yield nested distros
+    for subitem in metadata.resource_listdir('/'):
+        if subitem.endswith('.egg'):
+            subpath = os.path.join(path_item, subitem)
+            for dist in find_in_zip(zipimport.zipimporter(subpath), subpath):
+                yield dist
+
+register_finder(zipimport.zipimporter, find_in_zip)
+
+def StringIO(*args, **kw):
+    """Thunk to load the real StringIO on demand"""
+    global StringIO
+    try:
+        from io import StringIO
+    except ImportError:
+        from io import StringIO
+    return StringIO(*args,**kw)
+
+def find_nothing(importer, path_item, only=False):
+    return ()
+register_finder(object,find_nothing)
+
+def find_on_path(importer, path_item, only=False):
+    """Yield distributions accessible on a sys.path directory"""
+    path_item = _normalize_cached(path_item)
+
+    if os.path.isdir(path_item) and os.access(path_item, os.R_OK):
+        if path_item.lower().endswith('.egg'):
+            # unpacked egg
+            yield Distribution.from_filename(
+                path_item, metadata=PathMetadata(
+                    path_item, os.path.join(path_item,'EGG-INFO')
+                )
+            )
+        else:
+            # scan for .egg and .egg-info in directory
+            for entry in os.listdir(path_item):
+                lower = entry.lower()
+                if lower.endswith('.egg-info') or lower.endswith('.dist-info'):
+                    fullpath = os.path.join(path_item, entry)
+                    if os.path.isdir(fullpath):
+                        # egg-info directory, allow getting metadata
+                        metadata = PathMetadata(path_item, fullpath)
+                    else:
+                        metadata = FileMetadata(fullpath)
+                    yield Distribution.from_location(
+                        path_item,entry,metadata,precedence=DEVELOP_DIST
+                    )
+                elif not only and lower.endswith('.egg'):
+                    for dist in find_distributions(os.path.join(path_item, entry)):
+                        yield dist
+                elif not only and lower.endswith('.egg-link'):
+                    for line in open(os.path.join(path_item, entry)):
+                        if not line.strip(): continue
+                        for item in find_distributions(os.path.join(path_item,line.rstrip())):
+                            yield item
+                        break
+register_finder(ImpWrapper,find_on_path)
+
+try:
+    # CPython >=3.3
+    import _frozen_importlib
+except ImportError:
+    pass
+else:
+    register_finder(_frozen_importlib.FileFinder, find_on_path)
+
+_declare_state('dict', _namespace_handlers={})
+_declare_state('dict', _namespace_packages={})
+
+
+def register_namespace_handler(importer_type, namespace_handler):
+    """Register `namespace_handler` to declare namespace packages
+
+    `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item
+    handler), and `namespace_handler` is a callable like this::
+
+        def namespace_handler(importer,path_entry,moduleName,module):
+            # return a path_entry to use for child packages
+
+    Namespace handlers are only called if the importer object has already
+    agreed that it can handle the relevant path item, and they should only
+    return a subpath if the module __path__ does not already contain an
+    equivalent subpath.  For an example namespace handler, see
+    ``pkg_resources.file_ns_handler``.
+    """
+    _namespace_handlers[importer_type] = namespace_handler
+
+def _handle_ns(packageName, path_item):
+    """Ensure that named package includes a subpath of path_item (if needed)"""
+    importer = get_importer(path_item)
+    if importer is None:
+        return None
+    loader = importer.find_module(packageName)
+    if loader is None:
+        return None
+    module = sys.modules.get(packageName)
+    if module is None:
+        module = sys.modules[packageName] = types.ModuleType(packageName)
+        module.__path__ = []; _set_parent_ns(packageName)
+    elif not hasattr(module,'__path__'):
+        raise TypeError("Not a package:", packageName)
+    handler = _find_adapter(_namespace_handlers, importer)
+    subpath = handler(importer,path_item,packageName,module)
+    if subpath is not None:
+        path = module.__path__; path.append(subpath)
+        loader.load_module(packageName); module.__path__ = path
+    return subpath
+
+def declare_namespace(packageName):
+    """Declare that package 'packageName' is a namespace package"""
+
+    imp.acquire_lock()
+    try:
+        if packageName in _namespace_packages:
+            return
+
+        path, parent = sys.path, None
+        if '.' in packageName:
+            parent = '.'.join(packageName.split('.')[:-1])
+            declare_namespace(parent)
+            if parent not in _namespace_packages:
+                __import__(parent)
+            try:
+                path = sys.modules[parent].__path__
+            except AttributeError:
+                raise TypeError("Not a package:", parent)
+
+        # Track what packages are namespaces, so when new path items are added,
+        # they can be updated
+        _namespace_packages.setdefault(parent,[]).append(packageName)
+        _namespace_packages.setdefault(packageName,[])
+
+        for path_item in path:
+            # Ensure all the parent's path items are reflected in the child,
+            # if they apply
+            _handle_ns(packageName, path_item)
+
+    finally:
+        imp.release_lock()
+
+def fixup_namespace_packages(path_item, parent=None):
+    """Ensure that previously-declared namespace packages include path_item"""
+    imp.acquire_lock()
+    try:
+        for package in _namespace_packages.get(parent,()):
+            subpath = _handle_ns(package, path_item)
+            if subpath: fixup_namespace_packages(subpath,package)
+    finally:
+        imp.release_lock()
+
+def file_ns_handler(importer, path_item, packageName, module):
+    """Compute an ns-package subpath for a filesystem or zipfile importer"""
+
+    subpath = os.path.join(path_item, packageName.split('.')[-1])
+    normalized = _normalize_cached(subpath)
+    for item in module.__path__:
+        if _normalize_cached(item)==normalized:
+            break
+    else:
+        # Only return the path if it's not already there
+        return subpath
+
+register_namespace_handler(ImpWrapper,file_ns_handler)
+register_namespace_handler(zipimport.zipimporter,file_ns_handler)
+
+try:
+    # CPython >=3.3
+    import _frozen_importlib
+except ImportError:
+    pass
+else:
+    register_namespace_handler(_frozen_importlib.FileFinder, file_ns_handler)
+
+
+def null_ns_handler(importer, path_item, packageName, module):
+    return None
+
+register_namespace_handler(object,null_ns_handler)
+
+
+def normalize_path(filename):
+    """Normalize a file/dir name for comparison purposes"""
+    return os.path.normcase(os.path.realpath(filename))
+
+def _normalize_cached(filename,_cache={}):
+    try:
+        return _cache[filename]
+    except KeyError:
+        _cache[filename] = result = normalize_path(filename)
+        return result
+
+def _set_parent_ns(packageName):
+    parts = packageName.split('.')
+    name = parts.pop()
+    if parts:
+        parent = '.'.join(parts)
+        setattr(sys.modules[parent], name, sys.modules[packageName])
+
+
+def yield_lines(strs):
+    """Yield non-empty/non-comment lines of a ``basestring`` or sequence"""
+    if isinstance(strs,str):
+        for s in strs.splitlines():
+            s = s.strip()
+            if s and not s.startswith('#'):     # skip blank lines/comments
+                yield s
+    else:
+        for ss in strs:
+            for s in yield_lines(ss):
+                yield s
+
+LINE_END = re.compile(r"\s*(#.*)?$").match         # whitespace and comment
+CONTINUE = re.compile(r"\s*\\\s*(#.*)?$").match    # line continuation
+DISTRO   = re.compile(r"\s*((\w|[-.])+)").match    # Distribution or extra
+VERSION  = re.compile(r"\s*(<=?|>=?|==|!=)\s*((\w|[-.])+)").match  # ver. info
+COMMA    = re.compile(r"\s*,").match               # comma between items
+OBRACKET = re.compile(r"\s*\[").match
+CBRACKET = re.compile(r"\s*\]").match
+MODULE   = re.compile(r"\w+(\.\w+)*$").match
+EGG_NAME = re.compile(
+    r"(?P<name>[^-]+)"
+    r"( -(?P<ver>[^-]+) (-py(?P<pyver>[^-]+) (-(?P<plat>.+))? )? )?",
+    re.VERBOSE | re.IGNORECASE
+).match
+
+component_re = re.compile(r'(\d+ | [a-z]+ | \.| -)', re.VERBOSE)
+replace = {'pre':'c', 'preview':'c','-':'final-','rc':'c','dev':'@'}.get
+
+def _parse_version_parts(s):
+    for part in component_re.split(s):
+        part = replace(part,part)
+        if part in ['', '.']:
+            continue
+        if part[:1] in '0123456789':
+            yield part.zfill(8)    # pad for numeric comparison
+        else:
+            yield '*'+part
+
+    yield '*final'  # ensure that alpha/beta/candidate are before final
+
+def parse_version(s):
+    """Convert a version string to a chronologically-sortable key
+
+    This is a rough cross between distutils' StrictVersion and LooseVersion;
+    if you give it versions that would work with StrictVersion, then it behaves
+    the same; otherwise it acts like a slightly-smarter LooseVersion. It is
+    *possible* to create pathological version coding schemes that will fool
+    this parser, but they should be very rare in practice.
+
+    The returned value will be a tuple of strings.  Numeric portions of the
+    version are padded to 8 digits so they will compare numerically, but
+    without relying on how numbers compare relative to strings.  Dots are
+    dropped, but dashes are retained.  Trailing zeros between alpha segments
+    or dashes are suppressed, so that e.g. "2.4.0" is considered the same as
+    "2.4". Alphanumeric parts are lower-cased.
+
+    The algorithm assumes that strings like "-" and any alpha string that
+    alphabetically follows "final"  represents a "patch level".  So, "2.4-1"
+    is assumed to be a branch or patch of "2.4", and therefore "2.4.1" is
+    considered newer than "2.4-1", which in turn is newer than "2.4".
+
+    Strings like "a", "b", "c", "alpha", "beta", "candidate" and so on (that
+    come before "final" alphabetically) are assumed to be pre-release versions,
+    so that the version "2.4" is considered newer than "2.4a1".
+
+    Finally, to handle miscellaneous cases, the strings "pre", "preview", and
+    "rc" are treated as if they were "c", i.e. as though they were release
+    candidates, and therefore are not as new as a version string that does not
+    contain them, and "dev" is replaced with an '@' so that it sorts lower than
+    than any other pre-release tag.
+    """
+    parts = []
+    for part in _parse_version_parts(s.lower()):
+        if part.startswith('*'):
+            # remove trailing zeros from each series of numeric parts
+            while parts and parts[-1]=='00000000':
+                parts.pop()
+        parts.append(part)
+    return tuple(parts)
+
+class EntryPoint(object):
+    """Object representing an advertised importable object"""
+
+    def __init__(self, name, module_name, attrs=(), extras=(), dist=None):
+        if not MODULE(module_name):
+            raise ValueError("Invalid module name", module_name)
+        self.name = name
+        self.module_name = module_name
+        self.attrs = tuple(attrs)
+        self.extras = Requirement.parse(("x[%s]" % ','.join(extras))).extras
+        self.dist = dist
+
+    def __str__(self):
+        s = "%s = %s" % (self.name, self.module_name)
+        if self.attrs:
+            s += ':' + '.'.join(self.attrs)
+        if self.extras:
+            s += ' [%s]' % ','.join(self.extras)
+        return s
+
+    def __repr__(self):
+        return "EntryPoint.parse(%r)" % str(self)
+
+    def load(self, require=True, env=None, installer=None):
+        if require: self.require(env, installer)
+        entry = __import__(self.module_name, globals(),globals(), ['__name__'])
+        for attr in self.attrs:
+            try:
+                entry = getattr(entry,attr)
+            except AttributeError:
+                raise ImportError("%r has no %r attribute" % (entry,attr))
+        return entry
+
+    def require(self, env=None, installer=None):
+        if self.extras and not self.dist:
+            raise UnknownExtra("Can't require() without a distribution", self)
+        list(map(working_set.add,
+            working_set.resolve(self.dist.requires(self.extras),env,installer)))
+
+
+
+    #@classmethod
+    def parse(cls, src, dist=None):
+        """Parse a single entry point from string `src`
+
+        Entry point syntax follows the form::
+
+            name = some.module:some.attr [extra1,extra2]
+
+        The entry name and module name are required, but the ``:attrs`` and
+        ``[extras]`` parts are optional
+        """
+        try:
+            attrs = extras = ()
+            name,value = src.split('=',1)
+            if '[' in value:
+                value,extras = value.split('[',1)
+                req = Requirement.parse("x["+extras)
+                if req.specs: raise ValueError
+                extras = req.extras
+            if ':' in value:
+                value,attrs = value.split(':',1)
+                if not MODULE(attrs.rstrip()):
+                    raise ValueError
+                attrs = attrs.rstrip().split('.')
+        except ValueError:
+            raise ValueError(
+                "EntryPoint must be in 'name=module:attrs [extras]' format",
+                src
+            )
+        else:
+            return cls(name.strip(), value.strip(), attrs, extras, dist)
+
+    parse = classmethod(parse)
+
+
+
+
+
+
+
+
+    #@classmethod
+    def parse_group(cls, group, lines, dist=None):
+        """Parse an entry point group"""
+        if not MODULE(group):
+            raise ValueError("Invalid group name", group)
+        this = {}
+        for line in yield_lines(lines):
+            ep = cls.parse(line, dist)
+            if ep.name in this:
+                raise ValueError("Duplicate entry point", group, ep.name)
+            this[ep.name]=ep
+        return this
+
+    parse_group = classmethod(parse_group)
+
+    #@classmethod
+    def parse_map(cls, data, dist=None):
+        """Parse a map of entry point groups"""
+        if isinstance(data,dict):
+            data = list(data.items())
+        else:
+            data = split_sections(data)
+        maps = {}
+        for group, lines in data:
+            if group is None:
+                if not lines:
+                    continue
+                raise ValueError("Entry points must be listed in groups")
+            group = group.strip()
+            if group in maps:
+                raise ValueError("Duplicate group name", group)
+            maps[group] = cls.parse_group(group, lines, dist)
+        return maps
+
+    parse_map = classmethod(parse_map)
+
+
+def _remove_md5_fragment(location):
+    if not location:
+        return ''
+    parsed = urlparse(location)
+    if parsed[-1].startswith('md5='):
+        return urlunparse(parsed[:-1] + ('',))
+    return location
+
+
+class Distribution(object):
+    """Wrap an actual or potential sys.path entry w/metadata"""
+    PKG_INFO = 'PKG-INFO'
+    
+    def __init__(self,
+        location=None, metadata=None, project_name=None, version=None,
+        py_version=PY_MAJOR, platform=None, precedence = EGG_DIST
+    ):
+        self.project_name = safe_name(project_name or 'Unknown')
+        if version is not None:
+            self._version = safe_version(version)
+        self.py_version = py_version
+        self.platform = platform
+        self.location = location
+        self.precedence = precedence
+        self._provider = metadata or empty_provider
+
+    #@classmethod
+    def from_location(cls,location,basename,metadata=None,**kw):
+        project_name, version, py_version, platform = [None]*4
+        basename, ext = os.path.splitext(basename)
+        if ext.lower() in _distributionImpl:
+            # .dist-info gets much metadata differently
+            match = EGG_NAME(basename)
+            if match:
+                project_name, version, py_version, platform = match.group(
+                    'name','ver','pyver','plat'
+                )
+            cls = _distributionImpl[ext.lower()]
+        return cls(
+            location, metadata, project_name=project_name, version=version,
+            py_version=py_version, platform=platform, **kw
+        )
+    from_location = classmethod(from_location)
+
+
+    hashcmp = property(
+        lambda self: (
+            getattr(self,'parsed_version',()),
+            self.precedence,
+            self.key,
+            _remove_md5_fragment(self.location),
+            self.py_version,
+            self.platform
+        )
+    )
+    def __hash__(self): return hash(self.hashcmp)
+    def __lt__(self, other):
+        return self.hashcmp < other.hashcmp
+    def __le__(self, other):
+        return self.hashcmp <= other.hashcmp
+    def __gt__(self, other):
+        return self.hashcmp > other.hashcmp
+    def __ge__(self, other):
+        return self.hashcmp >= other.hashcmp
+    def __eq__(self, other):
+        if not isinstance(other, self.__class__):
+            # It's not a Distribution, so they are not equal
+            return False
+        return self.hashcmp == other.hashcmp
+    def __ne__(self, other):
+        return not self == other
+
+    # These properties have to be lazy so that we don't have to load any
+    # metadata until/unless it's actually needed.  (i.e., some distributions
+    # may not know their name or version without loading PKG-INFO)
+
+    #@property
+    def key(self):
+        try:
+            return self._key
+        except AttributeError:
+            self._key = key = self.project_name.lower()
+            return key
+    key = property(key)
+
+    #@property
+    def parsed_version(self):
+        try:
+            return self._parsed_version
+        except AttributeError:
+            self._parsed_version = pv = parse_version(self.version)
+            return pv
+
+    parsed_version = property(parsed_version)
+
+    #@property
+    def version(self):
+        try:
+            return self._version
+        except AttributeError:
+            for line in self._get_metadata(self.PKG_INFO):
+                if line.lower().startswith('version:'):
+                    self._version = safe_version(line.split(':',1)[1].strip())
+                    return self._version
+            else:
+                raise ValueError(
+                    "Missing 'Version:' header and/or %s file" % self.PKG_INFO, self
+                )
+    version = property(version)
+
+
+
+
+    #@property
+    def _dep_map(self):
+        try:
+            return self.__dep_map
+        except AttributeError:
+            dm = self.__dep_map = {None: []}
+            for name in 'requires.txt', 'depends.txt':
+                for extra,reqs in split_sections(self._get_metadata(name)):
+                    if extra: extra = safe_extra(extra)
+                    dm.setdefault(extra,[]).extend(parse_requirements(reqs))
+            return dm
+    _dep_map = property(_dep_map)
+
+    def requires(self,extras=()):
+        """List of Requirements needed for this distro if `extras` are used"""
+        dm = self._dep_map
+        deps = []
+        deps.extend(dm.get(None,()))
+        for ext in extras:
+            try:
+                deps.extend(dm[safe_extra(ext)])
+            except KeyError:
+                raise UnknownExtra(
+                    "%s has no such extra feature %r" % (self, ext)
+                )
+        return deps
+
+    def _get_metadata(self,name):
+        if self.has_metadata(name):
+            for line in self.get_metadata_lines(name):
+                yield line
+
+    def activate(self,path=None):
+        """Ensure distribution is importable on `path` (default=sys.path)"""
+        if path is None: path = sys.path
+        self.insert_on(path)
+        if path is sys.path:
+            fixup_namespace_packages(self.location)
+            list(map(declare_namespace, self._get_metadata('namespace_packages.txt')))
+
+
+    def egg_name(self):
+        """Return what this distribution's standard .egg filename should be"""
+        filename = "%s-%s-py%s" % (
+            to_filename(self.project_name), to_filename(self.version),
+            self.py_version or PY_MAJOR
+        )
+
+        if self.platform:
+            filename += '-'+self.platform
+        return filename
+
+    def __repr__(self):
+        if self.location:
+            return "%s (%s)" % (self,self.location)
+        else:
+            return str(self)
+
+    def __str__(self):
+        try: version = getattr(self,'version',None)
+        except ValueError: version = None
+        version = version or "[unknown version]"
+        return "%s %s" % (self.project_name,version)
+
+    def __getattr__(self,attr):
+        """Delegate all unrecognized public attributes to .metadata provider"""
+        if attr.startswith('_'):
+            raise AttributeError(attr)
+        return getattr(self._provider, attr)
+
+    #@classmethod
+    def from_filename(cls,filename,metadata=None, **kw):
+        return cls.from_location(
+            _normalize_cached(filename), os.path.basename(filename), metadata,
+            **kw
+        )
+    from_filename = classmethod(from_filename)
+
+    def as_requirement(self):
+        """Return a ``Requirement`` that matches this distribution exactly"""
+        return Requirement.parse('%s==%s' % (self.project_name, self.version))
+
+    def load_entry_point(self, group, name):
+        """Return the `name` entry point of `group` or raise ImportError"""
+        ep = self.get_entry_info(group,name)
+        if ep is None:
+            raise ImportError("Entry point %r not found" % ((group,name),))
+        return ep.load()
+
+    def get_entry_map(self, group=None):
+        """Return the entry point map for `group`, or the full entry map"""
+        try:
+            ep_map = self._ep_map
+        except AttributeError:
+            ep_map = self._ep_map = EntryPoint.parse_map(
+                self._get_metadata('entry_points.txt'), self
+            )
+        if group is not None:
+            return ep_map.get(group,{})
+        return ep_map
+
+    def get_entry_info(self, group, name):
+        """Return the EntryPoint object for `group`+`name`, or ``None``"""
+        return self.get_entry_map(group).get(name)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    def insert_on(self, path, loc = None):
+        """Insert self.location in path before its nearest parent directory"""
+
+        loc = loc or self.location
+
+        if self.project_name == 'setuptools':
+            try:
+                version = self.version
+            except ValueError:
+                version = ''
+            if '0.7' in version:
+                raise ValueError(
+                    "A 0.7-series setuptools cannot be installed "
+                    "with distribute. Found one at %s" % str(self.location))
+
+        if not loc:
+            return
+
+        if path is sys.path:
+            self.check_version_conflict()
+
+        nloc = _normalize_cached(loc)
+        bdir = os.path.dirname(nloc)
+        npath= list(map(_normalize_cached, path))
+
+        bp = None
+        for p, item in enumerate(npath):
+            if item==nloc:
+                break
+            elif item==bdir and self.precedence==EGG_DIST:
+                # if it's an .egg, give it precedence over its directory
+                path.insert(p, loc)
+                npath.insert(p, nloc)
+                break
+        else:
+            path.append(loc)
+            return
+
+        # p is the spot where we found or inserted loc; now remove duplicates
+        while 1:
+            try:
+                np = npath.index(nloc, p+1)
+            except ValueError:
+                break
+            else:
+                del npath[np], path[np]
+                p = np  # ha!
+
+        return
+
+
+
+    def check_version_conflict(self):
+        if self.key=='distribute':
+            return      # ignore the inevitable setuptools self-conflicts  :(
+
+        nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt'))
+        loc = normalize_path(self.location)
+        for modname in self._get_metadata('top_level.txt'):
+            if (modname not in sys.modules or modname in nsp
+                or modname in _namespace_packages
+            ):
+                continue
+            if modname in ('pkg_resources', 'setuptools', 'site'):
+                continue
+            fn = getattr(sys.modules[modname], '__file__', None)
+            if fn and (normalize_path(fn).startswith(loc) or
+                       fn.startswith(self.location)):
+                continue
+            issue_warning(
+                "Module %s was already imported from %s, but %s is being added"
+                " to sys.path" % (modname, fn, self.location),
+            )
+
+    def has_version(self):
+        try:
+            self.version
+        except ValueError:
+            issue_warning("Unbuilt egg for "+repr(self))
+            return False
+        return True
+
+    def clone(self,**kw):
+        """Copy this distribution, substituting in any changed keyword args"""
+        for attr in (
+            'project_name', 'version', 'py_version', 'platform', 'location',
+            'precedence'
+        ):
+            kw.setdefault(attr, getattr(self,attr,None))
+        kw.setdefault('metadata', self._provider)
+        return self.__class__(**kw)
+
+
+
+
+    #@property
+    def extras(self):
+        return [dep for dep in self._dep_map if dep]
+    extras = property(extras)
+
+
+class DistInfoDistribution(Distribution):
+    """Wrap an actual or potential sys.path entry w/metadata, .dist-info style"""
+    PKG_INFO = 'METADATA'
+    EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])")
+
+    @property
+    def _parsed_pkg_info(self):
+        """Parse and cache metadata"""
+        try:
+            return self._pkg_info
+        except AttributeError:
+            from email.parser import Parser
+            self._pkg_info = Parser().parsestr(self.get_metadata(self.PKG_INFO))
+            return self._pkg_info
+    
+    @property
+    def _dep_map(self):
+        try:
+            return self.__dep_map
+        except AttributeError:
+            self.__dep_map = self._compute_dependencies()
+            return self.__dep_map
+
+    def _preparse_requirement(self, requires_dist):
+        """Convert 'Foobar (1); baz' to ('Foobar ==1', 'baz')
+        Split environment marker, add == prefix to version specifiers as 
+        necessary, and remove parenthesis.
+        """
+        parts = requires_dist.split(';', 1) + ['']
+        distvers = parts[0].strip()
+        mark = parts[1].strip()
+        distvers = re.sub(self.EQEQ, r"\1==\2\3", distvers)
+        distvers = distvers.replace('(', '').replace(')', '')
+        return (distvers, mark)
+            
+    def _compute_dependencies(self):
+        """Recompute this distribution's dependencies."""
+        def dummy_marker(marker):
+            def marker_fn(environment=None, override=None):
+                return True
+            marker_fn.__doc__ = marker
+            return marker_fn
+        try:
+            from markerlib import as_function
+        except ImportError:
+            as_function = dummy_marker
+        dm = self.__dep_map = {None: []}
+
+        reqs = []
+        # Including any condition expressions
+        for req in self._parsed_pkg_info.get_all('Requires-Dist') or []:
+            distvers, mark = self._preparse_requirement(req)
+            parsed = next(parse_requirements(distvers))
+            parsed.marker_fn = as_function(mark)
+            reqs.append(parsed)
+            
+        def reqs_for_extra(extra):
+            for req in reqs:
+                if req.marker_fn(override={'extra':extra}):
+                    yield req
+
+        common = set(reqs_for_extra(None))
+        dm[None].extend(common)
+            
+        for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []:
+            extra = safe_extra(extra.strip())
+            dm[extra] = list(set(reqs_for_extra(extra)) - common)
+
+        return dm
+    
+
+_distributionImpl = {'.egg': Distribution,
+                     '.egg-info': Distribution,
+                     '.dist-info': DistInfoDistribution }
+
+
+def issue_warning(*args,**kw):
+    level = 1
+    g = globals()
+    try:
+        # find the first stack frame that is *not* code in
+        # the pkg_resources module, to use for the warning
+        while sys._getframe(level).f_globals is g:
+            level += 1
+    except ValueError:
+        pass
+    from warnings import warn
+    warn(stacklevel = level+1, *args, **kw)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+def parse_requirements(strs):
+    """Yield ``Requirement`` objects for each specification in `strs`
+
+    `strs` must be an instance of ``basestring``, or a (possibly-nested)
+    iterable thereof.
+    """
+    # create a steppable iterator, so we can handle \-continuations
+    lines = iter(yield_lines(strs))
+
+    def scan_list(ITEM,TERMINATOR,line,p,groups,item_name):
+
+        items = []
+
+        while not TERMINATOR(line,p):
+            if CONTINUE(line,p):
+                try:
+                    line = next(lines); p = 0
+                except StopIteration:
+                    raise ValueError(
+                        "\\ must not appear on the last nonblank line"
+                    )
+
+            match = ITEM(line,p)
+            if not match:
+                raise ValueError("Expected "+item_name+" in",line,"at",line[p:])
+
+            items.append(match.group(*groups))
+            p = match.end()
+
+            match = COMMA(line,p)
+            if match:
+                p = match.end() # skip the comma
+            elif not TERMINATOR(line,p):
+                raise ValueError(
+                    "Expected ',' or end-of-list in",line,"at",line[p:]
+                )
+
+        match = TERMINATOR(line,p)
+        if match: p = match.end()   # skip the terminator, if any
+        return line, p, items
+
+    for line in lines:
+        match = DISTRO(line)
+        if not match:
+            raise ValueError("Missing distribution spec", line)
+        project_name = match.group(1)
+        p = match.end()
+        extras = []
+
+        match = OBRACKET(line,p)
+        if match:
+            p = match.end()
+            line, p, extras = scan_list(
+                DISTRO, CBRACKET, line, p, (1,), "'extra' name"
+            )
+
+        line, p, specs = scan_list(VERSION,LINE_END,line,p,(1,2),"version spec")
+        specs = [(op,safe_version(val)) for op,val in specs]
+        yield Requirement(project_name, specs, extras)
+
+
+def _sort_dists(dists):
+    tmp = [(dist.hashcmp,dist) for dist in dists]
+    tmp.sort()
+    dists[::-1] = [d for hc,d in tmp]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+class Requirement:
+    def __init__(self, project_name, specs, extras):
+        """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
+        self.unsafe_name, project_name = project_name, safe_name(project_name)
+        self.project_name, self.key = project_name, project_name.lower()
+        index = [(parse_version(v),state_machine[op],op,v) for op,v in specs]
+        index.sort()
+        self.specs = [(op,ver) for parsed,trans,op,ver in index]
+        self.index, self.extras = index, tuple(map(safe_extra,extras))
+        self.hashCmp = (
+            self.key, tuple([(op,parsed) for parsed,trans,op,ver in index]),
+            frozenset(self.extras)
+        )
+        self.__hash = hash(self.hashCmp)
+
+    def __str__(self):
+        specs = ','.join([''.join(s) for s in self.specs])
+        extras = ','.join(self.extras)
+        if extras: extras = '[%s]' % extras
+        return '%s%s%s' % (self.project_name, extras, specs)
+
+    def __eq__(self,other):
+        return isinstance(other,Requirement) and self.hashCmp==other.hashCmp
+
+    def __contains__(self,item):
+        if isinstance(item,Distribution):
+            if item.key != self.key: return False
+            if self.index: item = item.parsed_version  # only get if we need it
+        elif isinstance(item,str):
+            item = parse_version(item)
+        last = None
+        compare = lambda a, b: (a > b) - (a < b) # -1, 0, 1
+        for parsed,trans,op,ver in self.index:
+            action = trans[compare(item,parsed)] # Indexing: 0, 1, -1
+            if action=='F':     return False
+            elif action=='T':   return True
+            elif action=='+':   last = True
+            elif action=='-' or last is None:   last = False
+        if last is None: last = True    # no rules encountered
+        return last
+
+
+    def __hash__(self):
+        return self.__hash
+
+    def __repr__(self): return "Requirement.parse(%r)" % str(self)
+
+    #@staticmethod
+    def parse(s, replacement=True):
+        reqs = list(parse_requirements(s))
+        if reqs:
+            if len(reqs) == 1:
+                founded_req = reqs[0]
+                # if asked for setuptools distribution
+                # and if distribute is installed, we want to give
+                # distribute instead
+                if _override_setuptools(founded_req) and replacement:
+                    distribute = list(parse_requirements('distribute'))
+                    if len(distribute) == 1:
+                        return distribute[0]
+                    return founded_req
+                else:
+                    return founded_req
+
+            raise ValueError("Expected only one requirement", s)
+        raise ValueError("No requirements found", s)
+
+    parse = staticmethod(parse)
+
+state_machine = {
+    #       =><
+    '<' :  '--T',
+    '<=':  'T-T',
+    '>' :  'F+F',
+    '>=':  'T+F',
+    '==':  'T..',
+    '!=':  'F++',
+}
+
+
+def _override_setuptools(req):
+    """Return True when distribute wants to override a setuptools dependency.
+
+    We want to override when the requirement is setuptools and the version is
+    a variant of 0.6.
+
+    """
+    if req.project_name == 'setuptools':
+        if not len(req.specs):
+            # Just setuptools: ok
+            return True
+        for comparator, version in req.specs:
+            if comparator in ['==', '>=', '>']:
+                if '0.7' in version:
+                    # We want some setuptools not from the 0.6 series.
+                    return False
+        return True
+    return False
+
+
+def _get_mro(cls):
+    """Get an mro for a type or classic class"""
+    if not isinstance(cls,type):
+        class cls(cls,object): pass
+        return cls.__mro__[1:]
+    return cls.__mro__
+
+def _find_adapter(registry, ob):
+    """Return an adapter factory for `ob` from `registry`"""
+    for t in _get_mro(getattr(ob, '__class__', type(ob))):
+        if t in registry:
+            return registry[t]
+
+
+def ensure_directory(path):
+    """Ensure that the parent directory of `path` exists"""
+    dirname = os.path.dirname(path)
+    if not os.path.isdir(dirname):
+        os.makedirs(dirname)
+
+def split_sections(s):
+    """Split a string or iterable thereof into (section,content) pairs
+
+    Each ``section`` is a stripped version of the section header ("[section]")
+    and each ``content`` is a list of stripped lines excluding blank lines and
+    comment-only lines.  If there are any such lines before the first section
+    header, they're returned in a first ``section`` of ``None``.
+    """
+    section = None
+    content = []
+    for line in yield_lines(s):
+        if line.startswith("["):
+            if line.endswith("]"):
+                if section or content:
+                    yield section, content
+                section = line[1:-1].strip()
+                content = []
+            else:
+                raise ValueError("Invalid section heading", line)
+        else:
+            content.append(line)
+
+    # wrap up last segment
+    yield section, content
+
+def _mkstemp(*args,**kw):
+    from tempfile import mkstemp
+    old_open = os.open
+    try:
+        os.open = os_open   # temporarily bypass sandboxing
+        return mkstemp(*args,**kw)
+    finally:
+        os.open = old_open  # and then put it back
+
+
+# Set up global resource manager (deliberately not state-saved)
+_manager = ResourceManager()
+def _initialize(g):
+    for name in dir(_manager):
+        if not name.startswith('_'):
+            g[name] = getattr(_manager, name)
+_initialize(globals())
+
+# Prepare the master working set and make the ``require()`` API available
+_declare_state('object', working_set = WorkingSet())
+
+try:
+    # Does the main program list any requirements?
+    from __main__ import __requires__
+except ImportError:
+    pass # No: just use the default working set based on sys.path
+else:
+    # Yes: ensure the requirements are met, by prefixing sys.path if necessary
+    try:
+        working_set.require(__requires__)
+    except VersionConflict:     # try it without defaults already on sys.path
+        working_set = WorkingSet([])    # by starting with an empty path
+        for dist in working_set.resolve(
+            parse_requirements(__requires__), Environment()
+        ):
+            working_set.add(dist)
+        for entry in sys.path:  # add any missing entries from sys.path
+            if entry not in working_set.entries:
+                working_set.add_entry(entry)
+        sys.path[:] = working_set.entries   # then copy back to sys.path
+
+require = working_set.require
+iter_entry_points = working_set.iter_entry_points
+add_activation_listener = working_set.subscribe
+run_script = working_set.run_script
+run_main = run_script   # backward compatibility
+# Activate all distributions already on sys.path, and ensure that
+# all distributions added to the working set in the future (e.g. by
+# calling ``require()``) will get activated as well.
+add_activation_listener(lambda dist: dist.activate())
+working_set.entries=[]; list(map(working_set.add_entry,sys.path)) # match order
+
diff --git a/lib3/Chameleon-2.9.2/tox.ini b/lib3/Chameleon-2.9.2/tox.ini
new file mode 100644
--- /dev/null
+++ b/lib3/Chameleon-2.9.2/tox.ini
@@ -0,0 +1,53 @@
+[tox]
+envlist = 
+    py25,py26,py27,py32,pypy,cover
+
+[testenv:py25]
+commands = 
+   python setup.py test -q
+deps = 
+    ordereddict
+    unittest2
+    distribute
+
+[testenv:py26]
+commands = 
+   python setup.py test -q
+deps = 
+    ordereddict
+    unittest2
+    distribute
+
+[testenv:py27]
+commands = 
+   python setup.py test -q
+deps = 
+    distribute
+
+[testenv:py32]
+commands = 
+   python setup.py test -q
+deps = 
+    distribute
+
+[testenv:pypy]
+commands = 
+   python setup.py test -q
+deps = 
+    ordereddict
+    unittest2
+    distribute
+
+[testenv:cover]
+basepython =
+    python2.6
+commands = 
+    python setup.py nosetests --with-xunit --with-xcoverage
+deps =
+    nose
+    coverage==3.4
+    nosexcover
+    ordereddict
+    unittest2
+    distribute
+
diff --git a/lib3/Mako-0.7.3/CHANGES b/lib3/Mako-0.7.3/CHANGES
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/CHANGES
@@ -0,0 +1,847 @@
+
+0.7.3
+- [bug] legacy_html_escape function, used when
+  Markupsafe isn't installed, was using an inline-compiled
+  regexp which causes major slowdowns on Python 3.3;
+  is now precompiled.
+
+- [bug] AST supporting now supports tuple-packed
+  function arguments inside pure-python def
+  or lambda expressions.  [ticket:201]
+
+- [bug] Fixed Py3K bug in the Babel extension.
+
+- [bug] Fixed the "filter" attribute of the
+  <%text> tag so that it pulls locally specified
+  identifiers from the context the same
+  way as that of <%block> and <%filter>.
+
+- [bug] Fixed bug in plugin loader to correctly
+  raise exception when non-existent plugin
+  is specified.
+
+0.7.2
+- [bug] Fixed regression in 0.7.1 where AST
+  parsing for Py2.4 was broken.
+  [ticket:193]
+
+0.7.1
+- [feature] Control lines with no bodies will
+  now succeed, as "pass" is added for these
+  when no statements are otherwise present.
+  Courtesy Ben Trofatter [ticket:146]
+
+- [bug] Fixed some long-broken scoping behavior
+  involving variables declared in defs and such,
+  which only became apparent when
+  the strict_undefined flag was turned on.
+  [ticket:192]
+
+- [bug] Can now use strict_undefined at the
+  same time args passed to def() are used
+  by other elements of the <%def> tag.
+  [ticket:191]
+
+0.7.0
+- [feature] Added new "loop" variable to templates,
+  is provided within a % for block to provide
+  info about the loop such as index, first/last,
+  odd/even, etc.  A migration path is also provided
+  for legacy templates via the "enable_loop" argument
+  available on Template, TemplateLookup, and <%page>.
+  Thanks to Ben Trofatter for all
+  the work on this [ticket:125]
+
+- [feature] Added a real check for "reserved"
+  names, that is names which are never pulled
+  from the context and cannot be passed to
+  the template.render() method.  Current names
+  are "context", "loop", "UNDEFINED".
+
+- [feature] The html_error_template() will now
+  apply Pygments highlighting to the source
+  code displayed in the traceback, if Pygments
+  if available.  Courtesy Ben Trofatter
+  [ticket:95]
+
+- [feature] Added support for context managers,
+  i.e. "% with x as e:/ % endwith" support.
+  Courtesy Ben Trofatter [ticket:147]
+
+- [feature] Added class-level flag to CacheImpl
+  "pass_context"; when True, the keyword argument
+  'context' will be passed to get_or_create()
+  containing the Mako Context object.
+  [ticket:185]
+
+- [bug] Fixed some Py3K resource warnings due
+  to filehandles being implicitly closed.
+  [ticket:182]
+
+- [bug] Fixed endless recursion bug when
+  nesting multiple def-calls with content.
+  Thanks to Jeff Dairiki. [ticket:186]
+
+- [feature] Added Jinja2 to the example
+  benchmark suite, courtesy Vincent Férotin
+
+0.6.2
+- [bug] The ${{"foo":"bar"}} parsing issue is fixed!!
+  The legendary Eevee has slain the dragon!
+  [ticket:20].  Also fixes quoting issue
+  at [ticket:86].
+
+0.6.1
+- [bug] Added special compatibility for the 0.5.0
+  Cache() constructor, which was preventing file
+  version checks and not allowing Mako 0.6 to
+  recompile the module files.
+
+0.6.0
+
+- [feature] Template caching has been converted into a plugin
+  system, whereby the usage of Beaker is just the
+  default plugin.   Template and TemplateLookup
+  now accept a string "cache_impl" parameter which
+  refers to the name of a cache plugin, defaulting
+  to the name 'beaker'.  New plugins can be
+  registered as pkg_resources entrypoints under
+  the group "mako.cache", or registered directly
+  using mako.cache.register_plugin().  The
+  core plugin is the mako.cache.CacheImpl
+  class.
+
+- [feature] Added support for Beaker cache regions
+  in templates.   Usage of regions should be considered
+  as superseding the very obsolete idea of passing in
+  backend options, timeouts, etc. within templates.
+
+- [feature] The 'put' method on Cache is now
+  'set'.  'put' is there for backwards compatibility.
+
+- [feature] The <%def>, <%block> and <%page> tags now accept
+  any argument named "cache_*", and the key
+  minus the "cache_" prefix will be passed as keyword
+  arguments to the CacheImpl methods.
+
+- [feature] Template and TemplateLookup now accept an argument
+  cache_args, which refers to a dictionary containing
+  cache parameters.  The cache_dir, cache_url, cache_type,
+  cache_timeout arguments are deprecated (will probably
+  never be removed, however) and can be passed
+  now as cache_args={'url':<some url>, 'type':'memcached',
+  'timeout':50, 'dir':'/path/to/some/directory'}
+
+- [feature/bug] Can now refer to context variables
+  within extra arguments to <%block>, <%def>, i.e.
+  <%block name="foo" cache_key="${somekey}">.
+  Filters can also be used in this way, i.e.
+  <%def name="foo()" filter="myfilter">
+  then template.render(myfilter=some_callable)
+  [ticket:180]
+
+- [feature] Added "--var name=value" option to the mako-render
+  script, allows passing of kw to the template from
+  the command line. [ticket:178]
+
+- [feature] Added module_writer argument to Template,
+  TemplateLookup, allows a callable to be passed which
+  takes over the writing of the template's module source
+  file, so that special environment-specific steps
+  can be taken.  [ticket:181]
+
+- [bug] The exception message in the html_error_template
+  is now escaped with the HTML filter. [ticket:142]
+
+- [bug] Added "white-space:pre" style to html_error_template()
+  for code blocks so that indentation is preserved
+  [ticket:173]
+
+- [bug] The "benchmark" example is now Python 3 compatible
+  (even though several of those old template libs aren't
+  available on Py3K, so YMMV) [ticket:175]
+
+0.5
+- A Template is explicitly disallowed
+  from having a url that normalizes to relative outside
+  of the root.   That is, if the Lookup is based
+  at /home/mytemplates, an include that would place
+  the ultimate template at
+  /home/mytemplates/../some_other_directory,
+  i.e. outside of /home/mytemplates,
+  is disallowed.   This usage was never intended
+  despite the lack of an explicit check.
+  The main issue this causes
+  is that module files can be written outside
+  of the module root (or raise an error, if file perms aren't
+  set up), and can also lead to the same template being
+  cached in the lookup under multiple, relative roots.
+  TemplateLookup instead has always supported multiple
+  file roots for this purpose.
+  [ticket:174]
+
+0.4.2
+- Fixed bug regarding <%call>/def calls w/ content
+  whereby the identity of the "caller" callable
+  inside the <%def> would be corrupted by the
+  presence of another <%call> in the same block.
+  [ticket:170]
+
+- Fixed the babel plugin to accommodate <%block>
+  [ticket:169]
+
+0.4.1
+- New tag: <%block>.  A variant on <%def> that
+  evaluates its contents in-place.
+  Can be named or anonymous,
+  the named version is intended for inheritance
+  layouts where any given section can be
+  surrounded by the <%block> tag in order for
+  it to become overrideable by inheriting
+  templates, without the need to specify a
+  top-level <%def> plus explicit call.
+  Modified scoping and argument rules as well as a
+  more strictly enforced usage scheme make it ideal
+  for this purpose without at all replacing most
+  other things that defs are still good for.
+  Lots of new docs. [ticket:164]
+
+- a slight adjustment to the "highlight" logic
+  for generating template bound stacktraces.
+  Will stick to known template source lines
+  without any extra guessing. [ticket:165]
+
+0.4.0
+- A 20% speedup for a basic two-page
+  inheritance setup rendering
+  a table of escaped data
+  (see http://techspot.zzzeek.org/2010/11/19/quick-mako-vs.-jinja-speed-test/).
+  A few configurational changes which
+  affect those in the I-don't-do-unicode
+  camp should be noted below.
+
+- The FastEncodingBuffer is now used
+  by default instead of cStringIO or StringIO,
+  regardless of whether output_encoding
+  is set to None or not.  FEB is faster than
+  both.  Only StringIO allows bytestrings
+  of unknown encoding to pass right
+  through, however - while it is of course
+  not recommended to send bytestrings of unknown
+  encoding to the output stream, this
+  mode of usage can be re-enabled by
+  setting the flag bytestring_passthrough
+  to True.
+
+- disable_unicode mode requires that
+  output_encoding be set to None - it also
+  forces the bytestring_passthrough flag
+  to True.
+
+- the <%namespace> tag raises an error
+  if the 'template' and 'module' attributes
+  are specified at the same time in
+  one tag.  A different class is used
+  for each case which allows a reduction in
+  runtime conditional logic and function
+  call overhead. [ticket:156]
+
+- the keys() in the Context, as well as
+  it's internal _data dictionary, now
+  include just what was specified to
+  render() as well as Mako builtins
+  'caller', 'capture'.  The contents
+  of __builtin__ are no longer copied.
+  Thanks to Daniel Lopez for pointing
+  this out. [ticket:159]
+
+0.3.6
+- Documentation is on Sphinx.
+  [ticket:126]
+
+- Beaker is now part of "extras" in
+  setup.py instead of "install_requires".
+  This to produce a lighter weight install
+  for those who don't use the caching
+  as well as to conform to Pyramid
+  deployment practices.  [ticket:154]
+
+- The Beaker import (or attempt thereof)
+  is delayed until actually needed;
+  this to remove the performance penalty
+  from startup, particularly for
+  "single execution" environments
+  such as shell scripts. [ticket:153]
+
+- Patch to lexer to not generate an empty
+  '' write in the case of backslash-ended
+  lines.  [ticket:155]
+
+- Fixed missing **extra collection in
+  setup.py which prevented setup.py
+  from running 2to3 on install.
+  [ticket:148]
+
+- New flag on Template, TemplateLookup -
+  strict_undefined=True, will cause
+  variables not found in the context to
+  raise a NameError immediately, instead of
+  defaulting to the UNDEFINED value.
+
+- The range of Python identifiers that
+  are considered "undefined", meaning they
+  are pulled from the context, has been
+  trimmed back to not include variables
+  declared inside of expressions (i.e. from
+  list comprehensions), as well as
+  in the argument list of lambdas.  This
+  to better support the strict_undefined
+  feature.  The change should be
+  fully backwards-compatible but involved
+  a little bit of tinkering in the AST code,
+  which hadn't really been touched for
+  a couple of years, just FYI.
+
+0.3.5
+- The <%namespace> tag allows expressions
+  for the `file` argument, i.e. with ${}.
+  The `context` variable, if needed,
+  must be referenced explicitly.
+  [ticket:141]
+
+- ${} expressions embedded in tags,
+  such as <%foo:bar x="${...}">, now
+  allow multiline Python expressions.
+
+- Fixed previously non-covered regular
+  expression, such that using a ${} expression
+  inside of a tag element that doesn't allow
+  them raises a CompileException instead of
+  silently failing.
+
+- Added a try/except around "import markupsafe".
+  This to support GAE which can't run markupsafe.
+  [ticket:151] No idea whatsoever if the
+  install_requires in setup.py also breaks GAE,
+  couldn't get an answer on this.
+
+0.3.4
+- Now using MarkupSafe for HTML escaping,
+  i.e. in place of cgi.escape().  Faster
+  C-based implementation and also escapes
+  single quotes for additional security.
+  Supports the __html__ attribute for
+  the given expression as well.
+
+  When using "disable_unicode" mode,
+  a pure Python HTML escaper function
+  is used which also quotes single quotes.
+
+  Note that Pylons by default doesn't
+  use Mako's filter - check your
+  environment.py file.
+
+- Fixed call to "unicode.strip" in
+  exceptions.text_error_template which
+  is not Py3k compatible.  [ticket:137]
+
+0.3.3
+- Added conditional to RichTraceback
+  such that if no traceback is passed
+  and sys.exc_info() has been reset,
+  the formatter just returns blank
+  for the "traceback" portion.
+  [ticket:135]
+
+- Fixed sometimes incorrect usage of
+  exc.__class__.__name__
+  in html/text error templates when using
+  Python 2.4 [ticket:131]
+
+- Fixed broken @property decorator on
+  template.last_modified
+
+- Fixed error formatting when a stacktrace
+  line contains no line number, as in when
+  inside an eval/exec-generated function.
+  [ticket:132]
+
+- When a .py is being created, the tempfile
+  where the source is stored temporarily is
+  now made in the same directory as that of
+  the .py file.  This ensures that the two
+  files share the same filesystem, thus
+  avoiding cross-filesystem synchronization
+  issues.  Thanks to Charles Cazabon.
+
+0.3.2
+- Calling a def from the top, via
+  template.get_def(...).render() now checks the
+  argument signature the same way as it did in
+  0.2.5, so that TypeError is not raised.
+  reopen of [ticket:116]
+
+
+0.3.1
+- Fixed incorrect dir name in setup.py
+  [ticket:129]
+
+0.3
+- Python 2.3 support is dropped. [ticket:123]
+
+- Python 3 support is added ! See README.py3k
+  for installation and testing notes.
+  [ticket:119]
+
+- Unit tests now run with nose.  [ticket:127]
+
+- Source code escaping has been simplified.
+  In particular, module source files are now
+  generated with the Python "magic encoding
+  comment", and source code is passed through
+  mostly unescaped, except for that code which
+  is regenerated from parsed Python source.
+  This fixes usage of unicode in
+  <%namespace:defname> tags.  [ticket:99]
+
+- RichTraceback(), html_error_template().render(),
+  text_error_template().render() now accept "error"
+  and "traceback" as optional arguments, and
+  these are now actually used.  [ticket:122]
+
+- The exception output generated when
+  format_exceptions=True will now be as a Python
+  unicode if it occurred during render_unicode(),
+  or an encoded string if during render().
+
+- A percent sign can be emitted as the first
+  non-whitespace character on a line by escaping
+  it as in "%%". [ticket:112]
+
+- Template accepts empty control structure, i.e.
+  % if: %endif, etc. [ticket:94]
+
+- The <%page args> tag can now be used in a base
+  inheriting template - the full set of render()
+  arguments are passed down through the inherits
+  chain.  Undeclared arguments go into **pageargs
+  as usual.  [ticket:116]
+
+- defs declared within a <%namespace> section, an
+  uncommon feature, have been improved.  The defs
+  no longer get doubly-rendered in the body() scope,
+  and now allow local variable assignment without
+  breakage.  [ticket:109]
+
+- Windows paths are handled correctly if a Template
+  is passed only an absolute filename (i.e. with c:
+  drive etc.)  and no URI - the URI is converted
+  to a forward-slash path and module_directory
+  is treated as a windows path.  [ticket:128]
+
+- TemplateLookup raises TopLevelLookupException for
+  a given path that is a directory, not a filename,
+  instead of passing through to the template to
+  generate IOError.  [ticket:73]
+
+0.2.6
+
+- Fix mako function decorators to preserve the
+  original function's name in all cases. Patch
+  from Scott Torborg.
+
+- Support the <%namespacename:defname> syntax in
+  the babel extractor. [ticket:118]
+
+- Further fixes to unicode handling of .py files with the
+  html_error_template. [ticket:88]
+
+0.2.5
+- Added a "decorator" kw argument to <%def>,
+  allows custom decoration functions to wrap
+  rendering callables.  Mainly intended for
+  custom caching algorithms, not sure what
+  other uses there may be (but there may be).
+  Examples are in the "filtering" docs.
+
+- When Mako creates subdirectories in which
+  to store templates, it uses the more
+  permissive mode of 0775 instead of 0750,
+  helping out with certain multi-process
+  scenarios. Note that the mode is always
+  subject to the restrictions of the existing
+  umask. [ticket:101]
+
+- Fixed namespace.__getattr__() to raise
+  AttributeError on attribute not found
+  instead of RuntimeError.  [ticket:104]
+
+- Added last_modified accessor to Template,
+  returns the time.time() when the module
+  was created. [ticket:97]
+
+- Fixed lexing support for whitespace
+  around '=' sign in defs. [ticket:102]
+
+- Removed errant "lower()" in the lexer which
+  was causing tags to compile with
+  case-insensitive names, thus messing up
+  custom <%call> names. [ticket:108]
+
+- added "mako.__version__" attribute to
+  the base module.  [ticket:110]
+
+0.2.4
+- Fixed compatibility with Jython 2.5b1.
+
+0.2.3
+- the <%namespacename:defname> syntax described at
+  http://techspot.zzzeek.org/?p=28 has now
+  been added as a built in syntax, and is recommended
+  as a more modern syntax versus <%call expr="expression">.
+  The %call tag itself will always remain,
+  with <%namespacename:defname> presenting a more HTML-like
+  alternative to calling defs, both plain and
+  nested.  Many examples of the new syntax are in the
+  "Calling a def with embedded content" section
+  of the docs.
+
+- added support for Jython 2.5.
+
+- cache module now uses Beaker's CacheManager
+  object directly, so that all cache types are included.
+  memcached is available as both "ext:memcached" and
+  "memcached", the latter for backwards compatibility.
+
+- added "cache" accessor to Template, Namespace.
+  e.g.  ${local.cache.get('somekey')} or
+  template.cache.invalidate_body()
+
+- added "cache_enabled=True" flag to Template,
+  TemplateLookup.  Setting this to False causes cache
+  operations to "pass through" and execute every time;
+  this flag should be integrated in Pylons with its own
+  cache_enabled configuration setting.
+
+- the Cache object now supports invalidate_def(name),
+  invalidate_body(), invalidate_closure(name),
+  invalidate(key), which will remove the given key
+  from the cache, if it exists.  The cache arguments
+  (i.e. storage type) are derived from whatever has
+  been already persisted for that template.
+  [ticket:92]
+
+- For cache changes to work fully, Beaker 1.1 is required.
+  1.0.1 and up will work as well with the exception of
+  cache expiry.  Note that Beaker 1.1 is **required**
+  for applications which use dynamically generated keys,
+  since previous versions will permanently store state in memory
+  for each individual key, thus consuming all available
+  memory for an arbitrarily large number of distinct
+  keys.
+
+- fixed bug whereby an <%included> template with
+  <%page> args named the same as a __builtin__ would not
+  honor the default value specified in <%page> [ticket:93]
+
+- fixed the html_error_template not handling tracebacks from
+  normal .py files with a magic encoding comment [ticket:88]
+
+- RichTraceback() now accepts an optional traceback object
+  to be used in place of sys.exc_info()[2].  html_error_template()
+  and text_error_template() accept an optional
+  render()-time argument "traceback" which is passed to the
+  RichTraceback object.
+
+- added ModuleTemplate class, which allows the construction
+  of a Template given a Python module generated by a previous
+  Template.   This allows Python modules alone to be used
+  as templates with no compilation step.   Source code
+  and template source are optional but allow error reporting
+  to work correctly.
+
+- fixed Python 2.3 compat. in mako.pyparser [ticket:90]
+
+- fix Babel 0.9.3 compatibility; stripping comment tags is now
+  optional (and enabled by default).
+
+
+0.2.2
+- cached blocks now use the current context when rendering
+an expired section, instead of the original context
+passed in [ticket:87]
+- fixed a critical issue regarding caching, whereby
+a cached block would raise an error when called within a
+cache-refresh operation that was initiated after the
+initiating template had completed rendering.
+
+0.2.1
+- fixed bug where 'output_encoding' parameter would prevent
+render_unicode() from returning a unicode object.
+- bumped magic number, which forces template recompile for
+this version (fixes incompatible compile symbols from 0.1
+series).
+- added a few docs for cache options, specifically those that
+help with memcached.
+
+0.2.0
+- Speed improvements (as though we needed them, but people
+  contributed and there you go):
+
+  - added "bytestring passthru" mode, via
+    `disable_unicode=True` argument passed to Template or
+    TemplateLookup. All unicode-awareness and filtering is
+    turned off, and template modules are generated with
+    the appropriate magic encoding comment. In this mode,
+    template expressions can only receive raw bytestrings
+    or Unicode objects which represent straight ASCII, and
+    render_unicode() may not be used if multibyte
+    characters are present. When enabled, speed
+    improvement around 10-20%. [ticket:77] (courtesy
+    anonymous guest)
+
+  - inlined the "write" function of Context into a local
+    template variable. This affords a 12-30% speedup in
+    template render time. (idea courtesy same anonymous
+    guest) [ticket:76]
+
+- New Features, API changes:
+
+  - added "attr" accessor to namespaces. Returns
+    attributes configured as module level attributes, i.e.
+    within <%! %> sections.  [ticket:62] i.e.:
+
+    # somefile.html
+    <%!
+        foo = 27
+    %>
+
+    # some other template
+    <%namespace name="myns" file="somefile.html"/>
+    ${myns.attr.foo}
+
+    The slight backwards incompatibility here is, you
+    can't have namespace defs named "attr" since the
+    "attr" descriptor will occlude it.
+
+  - cache_key argument can now render arguments passed
+    directly to the %page or %def, i.e. <%def
+    name="foo(x)" cached="True" cache_key="${x}"/>
+    [ticket:78]
+
+  - some functions on Context are now private:
+    _push_buffer(), _pop_buffer(),
+    caller_stack._push_frame(), caller_stack._pop_frame().
+
+  - added a runner script "mako-render" which renders
+    standard input as a template to stdout [ticket:81]
+    [ticket:56]
+
+- Bugfixes:
+  - can now use most names from __builtins__ as variable
+    names without explicit declaration (i.e. 'id',
+    'exception', 'range', etc.) [ticket:83] [ticket:84]
+
+  - can also use builtin names as local variable names
+    (i.e. dict, locals) (came from fix for [ticket:84])
+
+  - fixed bug in python generation when variable names are
+    used with identifiers like "else", "finally", etc.
+    inside them [ticket:68]
+
+  - fixed codegen bug which occured when using <%page>
+    level caching, combined with an expression-based
+    cache_key, combined with the usage of <%namespace
+    import="*"/> - fixed lexer exceptions not cleaning up
+    temporary files, which could lead to a maximum number
+    of file descriptors used in the process [ticket:69]
+
+  - fixed issue with inline format_exceptions that was
+    producing blank exception pages when an inheriting
+    template is present [ticket:71]
+
+  - format_exceptions will apply the encoding options of
+    html_error_template() to the buffered output
+
+  - rewrote the "whitespace adjuster" function to work
+    with more elaborate combinations of quotes and
+    comments [ticket:75]
+
+0.1.10
+- fixed propagation of 'caller' such that nested %def calls
+  within a <%call> tag's argument list propigates 'caller'
+  to the %call function itself (propigates to the inner
+  calls too, this is a slight side effect which previously
+  existed anyway)
+- fixed bug where local.get_namespace() could put an
+  incorrect "self" in the current context
+- fixed another namespace bug where the namespace functions
+  did not have access to the correct context containing
+  their 'self' and 'parent'
+
+0.1.9
+- filters.Decode filter can also accept a non-basestring
+object and will call str() + unicode() on it [ticket:47]
+- comments can be placed at the end of control lines,
+i.e. if foo: # a comment, [ticket:53], thanks to
+Paul Colomiets
+- fixed expressions and page tag arguments and with embedded
+newlines in CRLF templates, follow up to [ticket:16], thanks
+Eric Woroshow
+- added an IOError catch for source file not found in RichTraceback
+exception reporter [ticket:51]
+
+0.1.8
+- variable names declared in render methods by internal
+codegen prefixed by "__M_" to prevent name collisions
+with user code
+- added a Babel (http://babel.edgewall.org/) extractor entry
+point, allowing extraction of gettext messages directly from
+mako templates via Babel [ticket:45]
+- fix to turbogears plugin to work with dot-separated names
+(i.e. load_template('foo.bar')).  also takes file extension
+as a keyword argument (default is 'mak').
+- more tg fix:  fixed [ticket:35], allowing string-based
+templates with tgplugin even if non-compatible args were sent
+
+0.1.7
+- one small fix to the unit tests to support python 2.3
+- a slight hack to how cache.py detects Beaker's memcached,
+works around unexplained import behavior observed on some
+python 2.3 installations
+
+0.1.6
+- caching is now supplied directly by Beaker, which has
+  all of MyghtyUtils merged into it now.  The latest Beaker
+  (0.7.1) also fixes a bug related to how Mako was using the
+  cache API.
+- fix to module_directory path generation when the path is "./"
+  [ticket:34]
+- TGPlugin passes options to string-based templates [ticket:35]
+- added an explicit stack frame step to template runtime, which
+  allows much simpler and hopefully bug-free tracking of 'caller',
+  fixes #28
+- if plain Python defs are used with <%call>, a decorator
+  @runtime.supports_callable exists to ensure that the "caller"
+  stack is properly handled for the def.
+- fix to RichTraceback and exception reporting to get template
+  source code as a unicode object #37
+- html_error_template includes options "full=True", "css=True"
+  which control generation of HTML tags, CSS [ticket:39]
+- added the 'encoding_errors' parameter to Template/TemplateLookup
+  for specifying the error handler associated with encoding to
+  'output_encoding' [ticket:40]
+- the Template returned by html_error_template now defaults to
+  output_encoding=sys.getdefaultencoding(),
+  encoding_errors='htmlentityreplace' [ticket:37]
+- control lines, i.e. % lines, support backslashes to continue long
+  lines (#32)
+- fixed codegen bug when defining <%def> within <%call> within <%call>
+- leading utf-8 BOM in template files is honored according to pep-0263
+
+0.1.5
+- AST expression generation - added in just about everything
+  expression-wise from the AST module  [ticket:26]
+- AST parsing, properly detects imports of the form "import foo.bar"
+  [ticket:27]
+- fix to lexing of <%docs> tag nested in other tags
+- fix to context-arguments inside of <%include> tag which broke
+during 0.1.4 [ticket:29]
+- added "n" filter, disables *all* filters normally applied to an expression
+via <%page> or default_filters (but not those within the filter)
+- added buffer_filters argument, defines filters applied to the return value
+of buffered/cached/filtered %defs, after all filters defined with the %def
+itself have been applied.  allows the creation of default expression filters
+that let the output of return-valued %defs "opt out" of that filtering
+via passing special attributes or objects.
+
+0.1.4
+- got defs-within-defs to be cacheable
+- fixes to code parsing/whitespace adjusting where plain python comments
+  may contain quote characters [ticket:23]
+- fix to variable scoping for identifiers only referenced within
+  functions
+- added a path normalization step to lookup so URIs like
+  "/foo/bar/../etc/../foo" pre-process the ".." tokens before checking
+  the filesystem
+- fixed/improved "caller" semantics so that undefined caller is
+  "UNDEFINED", propigates __nonzero__ method so it evaulates to False if
+  not present, True otherwise. this way you can say % if caller:\n
+  ${caller.body()}\n% endif
+- <%include> has an "args" attribute that can pass arguments to the
+  called template (keyword arguments only, must be declared in that
+  page's <%page> tag.)
+- <%include> plus arguments is also programmatically available via
+  self.include_file(<filename>, **kwargs)
+- further escaping added for multibyte expressions in %def, %call
+  attributes [ticket:24]
+
+
+0.1.3
+- ***Small Syntax Change*** - the single line comment character is now
+*two* hash signs, i.e. "## this is a comment".  This avoids a common
+collection with CSS selectors.
+- the magic "coding" comment (i.e. # coding:utf-8) will still work with
+either one "#" sign or two for now; two is preferred going forward, i.e.
+## coding:<someencoding>.
+- new multiline comment form: "<%doc> a comment </%doc>"
+- UNDEFINED evaluates to False
+- improvement to scoping of "caller" variable when using <%call> tag
+- added lexer error for unclosed control-line (%) line
+- added "preprocessor" argument to Template, TemplateLookup - is a single
+  callable or list of callables which will be applied to the template text
+  before lexing.  given the text as an argument, returns the new text.
+- added mako.ext.preprocessors package, contains one preprocessor so far:
+  'convert_comments', which will convert single # comments to the new ##
+  format
+
+0.1.2
+- fix to parsing of code/expression blocks to insure that non-ascii
+  characters, combined with a template that indicates a non-standard
+  encoding, are expanded into backslash-escaped glyphs before being AST
+  parsed [ticket:11]
+- all template lexing converts the template to unicode first, to
+  immediately catch any encoding issues and ensure internal unicode
+  representation.
+- added module_filename argument to Template to allow specification of a
+  specific module file
+- added modulename_callable to TemplateLookup to allow a function to
+  determine module filenames (takes filename, uri arguments). used for
+  [ticket:14]
+- added optional input_encoding flag to Template, to allow sending a
+  unicode() object with no magic encoding comment
+- "expression_filter" argument in <%page> applies only to expressions
+- added "default_filters" argument to Template, TemplateLookup. applies only
+  to expressions, gets prepended to "expression_filter" arg from <%page>.
+  defaults to ["unicode"], so that all expressions get stringified into u''
+  by default (this is what Mako already does). By setting to [], expressions
+  are passed through raw.
+- added "imports" argument to Template, TemplateLookup. so you can predefine
+  a list of import statements at the top of the template. can be used in
+  conjunction with default_filters.
+- support for CRLF templates...whoops ! welcome to all the windows users.
+  [ticket:16]
+- small fix to local variable propigation for locals that are conditionally
+  declared
+- got "top level" def calls to work, i.e. template.get_def("somedef").render()
+
+0.1.1
+- buffet plugin supports string-based templates, allows ToscaWidgets to work
+  [ticket:8]
+- AST parsing fixes: fixed TryExcept identifier parsing
+- removed textmate tmbundle from contrib and into separate SVN location;
+  windows users cant handle those files, setuptools not very good at
+  "pruning" certain directories
+- fix so that "cache_timeout" parameter is propigated
+- fix to expression filters so that string conversion (actually unicode)
+  properly occurs before filtering
+- better error message when a lookup is attempted with a template that has no
+  lookup
+- implemented "module" attribute for namespace
+- fix to code generation to correctly track multiple defs with the same name
+- "directories" can be passed to TemplateLookup as a scalar in which case it
+  gets converted to a list [ticket:9]
+
+0.1.0
+
+Initial release.
diff --git a/lib3/Mako-0.7.3/LICENSE b/lib3/Mako-0.7.3/LICENSE
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/LICENSE
@@ -0,0 +1,20 @@
+This is the MIT license: http://www.opensource.org/licenses/mit-license.php
+
+Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>.
+Mako is a trademark of Michael Bayer.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this
+software and associated documentation files (the "Software"), to deal in the Software
+without restriction, including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/lib3/Mako-0.7.3/MANIFEST.in b/lib3/Mako-0.7.3/MANIFEST.in
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/MANIFEST.in
@@ -0,0 +1,11 @@
+# any kind of "*" pulls in __init__.pyc files,
+# so all extensions are explicit.
+
+recursive-include doc *.html *.css *.txt *.js *.png *.py Makefile *.rst *.mako
+recursive-include examples *.py *.xml *.mako *.myt *.kid *.tmpl
+recursive-include test *.py *.html *.mako
+
+include README* LICENSE distribute_setup.py ez_setup.py CHANGES*
+
+prune doc/build/output
+
diff --git a/lib3/Mako-0.7.3/Mako.egg-info/PKG-INFO b/lib3/Mako-0.7.3/Mako.egg-info/PKG-INFO
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/Mako.egg-info/PKG-INFO
@@ -0,0 +1,71 @@
+Metadata-Version: 1.0
+Name: Mako
+Version: 0.7.3
+Summary: A super-fast templating language that borrows the  best ideas from the existing templating languages.
+Home-page: http://www.makotemplates.org/
+Author: Mike Bayer
+Author-email: mike at zzzcomputing.com
+License: MIT
+Description: =========================
+        Mako Templates for Python
+        =========================
+        
+        Mako is a template library written in Python. It provides a familiar, non-XML 
+        syntax which compiles into Python modules for maximum performance. Mako's 
+        syntax and API borrows from the best ideas of many others, including Django
+        templates, Cheetah, Myghty, and Genshi. Conceptually, Mako is an embedded 
+        Python (i.e. Python Server Page) language, which refines the familiar ideas
+        of componentized layout and inheritance to produce one of the most 
+        straightforward and flexible models available, while also maintaining close 
+        ties to Python calling and scoping semantics.
+        
+        Nutshell
+        ========
+        
+        ::
+        
+            <%inherit file="base.html"/>
+            <%
+                rows = [[v for v in range(0,10)] for row in range(0,10)]
+            %>
+            <table>
+                % for row in rows:
+                    ${makerow(row)}
+                % endfor
+            </table>
+        
+            <%def name="makerow(row)">
+                <tr>
+                % for name in row:
+                    <td>${name}</td>\
+                % endfor
+                </tr>
+            </%def>
+        
+        Philosophy
+        ===========
+        
+        Python is a great scripting language. Don't reinvent the wheel...your templates can handle it !
+        
+        Documentation
+        ==============
+        
+        See documentation for Mako at http://www.makotemplates.org/docs/
+        
+        License
+        ========
+        
+        Mako is licensed under an MIT-style license (see LICENSE).
+        Other incorporated projects may be licensed under different licenses.
+        All licenses allow for non-commercial and commercial use.
+        
+Keywords: templates
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
diff --git a/lib3/Mako-0.7.3/Mako.egg-info/SOURCES.txt b/lib3/Mako-0.7.3/Mako.egg-info/SOURCES.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/Mako.egg-info/SOURCES.txt
@@ -0,0 +1,171 @@
+CHANGES
+LICENSE
+MANIFEST.in
+README.rst
+distribute_setup.py
+setup.cfg
+setup.py
+Mako.egg-info/PKG-INFO
+Mako.egg-info/SOURCES.txt
+Mako.egg-info/dependency_links.txt
+Mako.egg-info/entry_points.txt
+Mako.egg-info/not-zip-safe
+Mako.egg-info/requires.txt
+Mako.egg-info/top_level.txt
+doc/caching.html
+doc/defs.html
+doc/filtering.html
+doc/genindex.html
+doc/index.html
+doc/inheritance.html
+doc/namespaces.html
+doc/runtime.html
+doc/search.html
+doc/searchindex.js
+doc/syntax.html
+doc/unicode.html
+doc/usage.html
+doc/_sources/caching.txt
+doc/_sources/defs.txt
+doc/_sources/filtering.txt
+doc/_sources/index.txt
+doc/_sources/inheritance.txt
+doc/_sources/namespaces.txt
+doc/_sources/runtime.txt
+doc/_sources/syntax.txt
+doc/_sources/unicode.txt
+doc/_sources/usage.txt
+doc/_static/basic.css
+doc/_static/comment-bright.png
+doc/_static/comment-close.png
+doc/_static/comment.png
+doc/_static/default.css
+doc/_static/docs.css
+doc/_static/doctools.js
+doc/_static/down-pressed.png
+doc/_static/down.png
+doc/_static/file.png
+doc/_static/jquery.js
+doc/_static/makoLogo.png
+doc/_static/minus.png
+doc/_static/plus.png
+doc/_static/pygments.css
+doc/_static/searchtools.js
+doc/_static/sidebar.js
+doc/_static/site.css
+doc/_static/underscore.js
+doc/_static/up-pressed.png
+doc/_static/up.png
+doc/_static/websupport.js
+doc/build/Makefile
+doc/build/caching.rst
+doc/build/conf.py
+doc/build/defs.rst
+doc/build/filtering.rst
+doc/build/index.rst
+doc/build/inheritance.rst
+doc/build/namespaces.rst
+doc/build/runtime.rst
+doc/build/syntax.rst
+doc/build/unicode.rst
+doc/build/usage.rst
+doc/build/builder/__init__.py
+doc/build/builder/builders.py
+doc/build/builder/util.py
+doc/build/static/docs.css
+doc/build/static/makoLogo.png
+doc/build/static/site.css
+doc/build/templates/base.mako
+doc/build/templates/genindex.mako
+doc/build/templates/layout.mako
+doc/build/templates/page.mako
+doc/build/templates/rtd_layout.mako
+doc/build/templates/search.mako
+examples/bench/basic.py
+examples/bench/cheetah/footer.tmpl
+examples/bench/cheetah/header.tmpl
+examples/bench/cheetah/template.tmpl
+examples/bench/django/templatetags/__init__.py
+examples/bench/django/templatetags/bench.py
+examples/bench/kid/base.kid
+examples/bench/kid/template.kid
+examples/bench/myghty/base.myt
+examples/bench/myghty/template.myt
+examples/wsgi/run_wsgi.py
+mako/__init__.py
+mako/_ast_util.py
+mako/ast.py
+mako/cache.py
+mako/codegen.py
+mako/exceptions.py
+mako/filters.py
+mako/lexer.py
+mako/lookup.py
+mako/parsetree.py
+mako/pygen.py
+mako/pyparser.py
+mako/runtime.py
+mako/template.py
+mako/util.py
+mako/ext/__init__.py
+mako/ext/autohandler.py
+mako/ext/babelplugin.py
+mako/ext/beaker_cache.py
+mako/ext/preprocessors.py
+mako/ext/pygmentplugin.py
+mako/ext/turbogears.py
+scripts/mako-render
+test/__init__.py
+test/sample_module_namespace.py
+test/test_ast.py
+test/test_babelplugin.py
+test/test_block.py
+test/test_cache.py
+test/test_call.py
+test/test_decorators.py
+test/test_def.py
+test/test_exceptions.py
+test/test_filters.py
+test/test_inheritance.py
+test/test_lexer.py
+test/test_lookup.py
+test/test_loop.py
+test/test_lru.py
+test/test_namespace.py
+test/test_pygen.py
+test/test_template.py
+test/test_tgplugin.py
+test/test_util.py
+test/util.py
+test/foo/__init__.py
+test/foo/test_ns.py
+test/templates/badbom.html
+test/templates/bom.html
+test/templates/bommagic.html
+test/templates/chs_unicode.html
+test/templates/chs_unicode_py3k.html
+test/templates/chs_utf8.html
+test/templates/crlf.html
+test/templates/gettext.mako
+test/templates/index.html
+test/templates/internationalization.html
+test/templates/modtest.html
+test/templates/read_unicode.html
+test/templates/read_unicode_py3k.html
+test/templates/runtimeerr.html
+test/templates/runtimeerr_py3k.html
+test/templates/unicode.html
+test/templates/unicode_arguments.html
+test/templates/unicode_arguments_py3k.html
+test/templates/unicode_code.html
+test/templates/unicode_code_py3k.html
+test/templates/unicode_expr.html
+test/templates/unicode_expr_py3k.html
+test/templates/unicode_runtime_error.html
+test/templates/unicode_syntax_error.html
+test/templates/foo/modtest.html.py
+test/templates/othersubdir/foo.html
+test/templates/subdir/incl.html
+test/templates/subdir/index.html
+test/templates/subdir/modtest.html
+test/templates/subdir/foo/modtest.html.py
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/Mako.egg-info/dependency_links.txt b/lib3/Mako-0.7.3/Mako.egg-info/dependency_links.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/Mako.egg-info/dependency_links.txt
@@ -0,0 +1,1 @@
+
diff --git a/lib3/Mako-0.7.3/Mako.egg-info/entry_points.txt b/lib3/Mako-0.7.3/Mako.egg-info/entry_points.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/Mako.egg-info/entry_points.txt
@@ -0,0 +1,14 @@
+
+      [python.templating.engines]
+      mako = mako.ext.turbogears:TGPlugin
+ 
+      [pygments.lexers]
+      mako = mako.ext.pygmentplugin:MakoLexer
+      html+mako = mako.ext.pygmentplugin:MakoHtmlLexer
+      xml+mako = mako.ext.pygmentplugin:MakoXmlLexer
+      js+mako = mako.ext.pygmentplugin:MakoJavascriptLexer
+      css+mako = mako.ext.pygmentplugin:MakoCssLexer
+
+      [babel.extractors]
+      mako = mako.ext.babelplugin:extract
+      
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/Mako.egg-info/not-zip-safe b/lib3/Mako-0.7.3/Mako.egg-info/not-zip-safe
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/Mako.egg-info/not-zip-safe
@@ -0,0 +1,1 @@
+
diff --git a/lib3/Mako-0.7.3/Mako.egg-info/requires.txt b/lib3/Mako-0.7.3/Mako.egg-info/requires.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/Mako.egg-info/requires.txt
@@ -0,0 +1,4 @@
+MarkupSafe>=0.9.2
+
+[beaker]
+Beaker>=1.1
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/Mako.egg-info/top_level.txt b/lib3/Mako-0.7.3/Mako.egg-info/top_level.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/Mako.egg-info/top_level.txt
@@ -0,0 +1,1 @@
+mako
diff --git a/lib3/Mako-0.7.3/PKG-INFO b/lib3/Mako-0.7.3/PKG-INFO
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/PKG-INFO
@@ -0,0 +1,71 @@
+Metadata-Version: 1.0
+Name: Mako
+Version: 0.7.3
+Summary: A super-fast templating language that borrows the  best ideas from the existing templating languages.
+Home-page: http://www.makotemplates.org/
+Author: Mike Bayer
+Author-email: mike at zzzcomputing.com
+License: MIT
+Description: =========================
+        Mako Templates for Python
+        =========================
+        
+        Mako is a template library written in Python. It provides a familiar, non-XML 
+        syntax which compiles into Python modules for maximum performance. Mako's 
+        syntax and API borrows from the best ideas of many others, including Django
+        templates, Cheetah, Myghty, and Genshi. Conceptually, Mako is an embedded 
+        Python (i.e. Python Server Page) language, which refines the familiar ideas
+        of componentized layout and inheritance to produce one of the most 
+        straightforward and flexible models available, while also maintaining close 
+        ties to Python calling and scoping semantics.
+        
+        Nutshell
+        ========
+        
+        ::
+        
+            <%inherit file="base.html"/>
+            <%
+                rows = [[v for v in range(0,10)] for row in range(0,10)]
+            %>
+            <table>
+                % for row in rows:
+                    ${makerow(row)}
+                % endfor
+            </table>
+        
+            <%def name="makerow(row)">
+                <tr>
+                % for name in row:
+                    <td>${name}</td>\
+                % endfor
+                </tr>
+            </%def>
+        
+        Philosophy
+        ===========
+        
+        Python is a great scripting language. Don't reinvent the wheel...your templates can handle it !
+        
+        Documentation
+        ==============
+        
+        See documentation for Mako at http://www.makotemplates.org/docs/
+        
+        License
+        ========
+        
+        Mako is licensed under an MIT-style license (see LICENSE).
+        Other incorporated projects may be licensed under different licenses.
+        All licenses allow for non-commercial and commercial use.
+        
+Keywords: templates
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
diff --git a/lib3/Mako-0.7.3/README.rst b/lib3/Mako-0.7.3/README.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/README.rst
@@ -0,0 +1,52 @@
+=========================
+Mako Templates for Python
+=========================
+
+Mako is a template library written in Python. It provides a familiar, non-XML 
+syntax which compiles into Python modules for maximum performance. Mako's 
+syntax and API borrows from the best ideas of many others, including Django
+templates, Cheetah, Myghty, and Genshi. Conceptually, Mako is an embedded 
+Python (i.e. Python Server Page) language, which refines the familiar ideas
+of componentized layout and inheritance to produce one of the most 
+straightforward and flexible models available, while also maintaining close 
+ties to Python calling and scoping semantics.
+
+Nutshell
+========
+
+::
+
+    <%inherit file="base.html"/>
+    <%
+        rows = [[v for v in range(0,10)] for row in range(0,10)]
+    %>
+    <table>
+        % for row in rows:
+            ${makerow(row)}
+        % endfor
+    </table>
+
+    <%def name="makerow(row)">
+        <tr>
+        % for name in row:
+            <td>${name}</td>\
+        % endfor
+        </tr>
+    </%def>
+
+Philosophy
+===========
+
+Python is a great scripting language. Don't reinvent the wheel...your templates can handle it !
+
+Documentation
+==============
+
+See documentation for Mako at http://www.makotemplates.org/docs/
+
+License
+========
+
+Mako is licensed under an MIT-style license (see LICENSE).
+Other incorporated projects may be licensed under different licenses.
+All licenses allow for non-commercial and commercial use.
diff --git a/lib3/Mako-0.7.3/distribute_setup.py b/lib3/Mako-0.7.3/distribute_setup.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/distribute_setup.py
@@ -0,0 +1,485 @@
+#!python
+"""Bootstrap distribute installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+    from distribute_setup import use_setuptools
+    use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import os
+import sys
+import time
+import fnmatch
+import tempfile
+import tarfile
+from distutils import log
+
+try:
+    from site import USER_SITE
+except ImportError:
+    USER_SITE = None
+
+try:
+    import subprocess
+
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        return subprocess.call(args) == 0
+
+except ImportError:
+    # will be used for python 2.3
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        # quoting arguments if windows
+        if sys.platform == 'win32':
+            def quote(arg):
+                if ' ' in arg:
+                    return '"%s"' % arg
+                return arg
+            args = [quote(arg) for arg in args]
+        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
+
+DEFAULT_VERSION = "0.6.13"
+DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
+SETUPTOOLS_FAKED_VERSION = "0.6c11"
+
+SETUPTOOLS_PKG_INFO = """\
+Metadata-Version: 1.0
+Name: setuptools
+Version: %s
+Summary: xxxx
+Home-page: xxx
+Author: xxx
+Author-email: xxx
+License: xxx
+Description: xxx
+""" % SETUPTOOLS_FAKED_VERSION
+
+
+def _install(tarball):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # installing
+        log.warn('Installing Distribute')
+        if not _python_cmd('setup.py', 'install'):
+            log.warn('Something went wrong during the installation.')
+            log.warn('See the error message above.')
+    finally:
+        os.chdir(old_wd)
+
+
+def _build_egg(egg, tarball, to_dir):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # building an egg
+        log.warn('Building a Distribute egg in %s', to_dir)
+        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
+
+    finally:
+        os.chdir(old_wd)
+    # returning the result
+    log.warn(egg)
+    if not os.path.exists(egg):
+        raise IOError('Could not build the egg.')
+
+
+def _do_download(version, download_base, to_dir, download_delay):
+    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
+                       % (version, sys.version_info[0], sys.version_info[1]))
+    if not os.path.exists(egg):
+        tarball = download_setuptools(version, download_base,
+                                      to_dir, download_delay)
+        _build_egg(egg, tarball, to_dir)
+    sys.path.insert(0, egg)
+    import setuptools
+    setuptools.bootstrap_install_from = egg
+
+
+def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                   to_dir=os.curdir, download_delay=15, no_fake=True):
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    was_imported = 'pkg_resources' in sys.modules or \
+        'setuptools' in sys.modules
+    try:
+        try:
+            import pkg_resources
+            if not hasattr(pkg_resources, '_distribute'):
+                if not no_fake:
+                    _fake_setuptools()
+                raise ImportError
+        except ImportError:
+            return _do_download(version, download_base, to_dir, download_delay)
+        try:
+            pkg_resources.require("distribute>="+version)
+            return
+        except pkg_resources.VersionConflict:
+            e = sys.exc_info()[1]
+            if was_imported:
+                sys.stderr.write(
+                "The required version of distribute (>=%s) is not available,\n"
+                "and can't be installed while this script is running. Please\n"
+                "install a more recent version first, using\n"
+                "'easy_install -U distribute'."
+                "\n\n(Currently using %r)\n" % (version, e.args[0]))
+                sys.exit(2)
+            else:
+                del pkg_resources, sys.modules['pkg_resources']    # reload ok
+                return _do_download(version, download_base, to_dir,
+                                    download_delay)
+        except pkg_resources.DistributionNotFound:
+            return _do_download(version, download_base, to_dir,
+                                download_delay)
+    finally:
+        if not no_fake:
+            _create_fake_setuptools_pkg_info(to_dir)
+
+def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                        to_dir=os.curdir, delay=15):
+    """Download distribute from a specified location and return its filename
+
+    `version` should be a valid distribute version number that is available
+    as an egg for download under the `download_base` URL (which should end
+    with a '/'). `to_dir` is the directory where the egg will be downloaded.
+    `delay` is the number of seconds to pause before an actual download
+    attempt.
+    """
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    try:
+        from urllib.request import urlopen
+    except ImportError:
+        from urllib.request import urlopen
+    tgz_name = "distribute-%s.tar.gz" % version
+    url = download_base + tgz_name
+    saveto = os.path.join(to_dir, tgz_name)
+    src = dst = None
+    if not os.path.exists(saveto):  # Avoid repeated downloads
+        try:
+            log.warn("Downloading %s", url)
+            src = urlopen(url)
+            # Read/write all in one block, so we don't create a corrupt file
+            # if the download is interrupted.
+            data = src.read()
+            dst = open(saveto, "wb")
+            dst.write(data)
+        finally:
+            if src:
+                src.close()
+            if dst:
+                dst.close()
+    return os.path.realpath(saveto)
+
+def _no_sandbox(function):
+    def __no_sandbox(*args, **kw):
+        try:
+            from setuptools.sandbox import DirectorySandbox
+            if not hasattr(DirectorySandbox, '_old'):
+                def violation(*args):
+                    pass
+                DirectorySandbox._old = DirectorySandbox._violation
+                DirectorySandbox._violation = violation
+                patched = True
+            else:
+                patched = False
+        except ImportError:
+            patched = False
+
+        try:
+            return function(*args, **kw)
+        finally:
+            if patched:
+                DirectorySandbox._violation = DirectorySandbox._old
+                del DirectorySandbox._old
+
+    return __no_sandbox
+
+def _patch_file(path, content):
+    """Will backup the file then patch it"""
+    existing_content = open(path).read()
+    if existing_content == content:
+        # already patched
+        log.warn('Already patched.')
+        return False
+    log.warn('Patching...')
+    _rename_path(path)
+    f = open(path, 'w')
+    try:
+        f.write(content)
+    finally:
+        f.close()
+    return True
+
+_patch_file = _no_sandbox(_patch_file)
+
+def _same_content(path, content):
+    return open(path).read() == content
+
+def _rename_path(path):
+    new_name = path + '.OLD.%s' % time.time()
+    log.warn('Renaming %s into %s', path, new_name)
+    os.rename(path, new_name)
+    return new_name
+
+def _remove_flat_installation(placeholder):
+    if not os.path.isdir(placeholder):
+        log.warn('Unkown installation at %s', placeholder)
+        return False
+    found = False
+    for file in os.listdir(placeholder):
+        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
+            found = True
+            break
+    if not found:
+        log.warn('Could not locate setuptools*.egg-info')
+        return
+
+    log.warn('Removing elements out of the way...')
+    pkg_info = os.path.join(placeholder, file)
+    if os.path.isdir(pkg_info):
+        patched = _patch_egg_dir(pkg_info)
+    else:
+        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
+
+    if not patched:
+        log.warn('%s already patched.', pkg_info)
+        return False
+    # now let's move the files out of the way
+    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
+        element = os.path.join(placeholder, element)
+        if os.path.exists(element):
+            _rename_path(element)
+        else:
+            log.warn('Could not find the %s element of the '
+                     'Setuptools distribution', element)
+    return True
+
+_remove_flat_installation = _no_sandbox(_remove_flat_installation)
+
+def _after_install(dist):
+    log.warn('After install bootstrap.')
+    placeholder = dist.get_command_obj('install').install_purelib
+    _create_fake_setuptools_pkg_info(placeholder)
+
+def _create_fake_setuptools_pkg_info(placeholder):
+    if not placeholder or not os.path.exists(placeholder):
+        log.warn('Could not find the install location')
+        return
+    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
+    setuptools_file = 'setuptools-%s-py%s.egg-info' % \
+            (SETUPTOOLS_FAKED_VERSION, pyver)
+    pkg_info = os.path.join(placeholder, setuptools_file)
+    if os.path.exists(pkg_info):
+        log.warn('%s already exists', pkg_info)
+        return
+
+    log.warn('Creating %s', pkg_info)
+    f = open(pkg_info, 'w')
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+
+    pth_file = os.path.join(placeholder, 'setuptools.pth')
+    log.warn('Creating %s', pth_file)
+    f = open(pth_file, 'w')
+    try:
+        f.write(os.path.join(os.curdir, setuptools_file))
+    finally:
+        f.close()
+
+_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
+
+def _patch_egg_dir(path):
+    # let's check if it's already patched
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    if os.path.exists(pkg_info):
+        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
+            log.warn('%s already patched.', pkg_info)
+            return False
+    _rename_path(path)
+    os.mkdir(path)
+    os.mkdir(os.path.join(path, 'EGG-INFO'))
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    f = open(pkg_info, 'w')
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+    return True
+
+_patch_egg_dir = _no_sandbox(_patch_egg_dir)
+
+def _before_install():
+    log.warn('Before install bootstrap.')
+    _fake_setuptools()
+
+
+def _under_prefix(location):
+    if 'install' not in sys.argv:
+        return True
+    args = sys.argv[sys.argv.index('install')+1:]
+    for index, arg in enumerate(args):
+        for option in ('--root', '--prefix'):
+            if arg.startswith('%s=' % option):
+                top_dir = arg.split('root=')[-1]
+                return location.startswith(top_dir)
+            elif arg == option:
+                if len(args) > index:
+                    top_dir = args[index+1]
+                    return location.startswith(top_dir)
+        if arg == '--user' and USER_SITE is not None:
+            return location.startswith(USER_SITE)
+    return True
+
+
+def _fake_setuptools():
+    log.warn('Scanning installed packages')
+    try:
+        import pkg_resources
+    except ImportError:
+        # we're cool
+        log.warn('Setuptools or Distribute does not seem to be installed.')
+        return
+    ws = pkg_resources.working_set
+    try:
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
+                                  replacement=False))
+    except TypeError:
+        # old distribute API
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+
+    if setuptools_dist is None:
+        log.warn('No setuptools distribution found')
+        return
+    # detecting if it was already faked
+    setuptools_location = setuptools_dist.location
+    log.warn('Setuptools installation detected at %s', setuptools_location)
+
+    # if --root or --preix was provided, and if
+    # setuptools is not located in them, we don't patch it
+    if not _under_prefix(setuptools_location):
+        log.warn('Not patching, --root or --prefix is installing Distribute'
+                 ' in another location')
+        return
+
+    # let's see if its an egg
+    if not setuptools_location.endswith('.egg'):
+        log.warn('Non-egg installation')
+        res = _remove_flat_installation(setuptools_location)
+        if not res:
+            return
+    else:
+        log.warn('Egg installation')
+        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
+        if (os.path.exists(pkg_info) and
+            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
+            log.warn('Already patched.')
+            return
+        log.warn('Patching...')
+        # let's create a fake egg replacing setuptools one
+        res = _patch_egg_dir(setuptools_location)
+        if not res:
+            return
+    log.warn('Patched done.')
+    _relaunch()
+
+
+def _relaunch():
+    log.warn('Relaunching...')
+    # we have to relaunch the process
+    # pip marker to avoid a relaunch bug
+    if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
+        sys.argv[0] = 'setup.py'
+    args = [sys.executable] + sys.argv
+    sys.exit(subprocess.call(args))
+
+
+def _extractall(self, path=".", members=None):
+    """Extract all members from the archive to the current working
+       directory and set owner, modification time and permissions on
+       directories afterwards. `path' specifies a different directory
+       to extract to. `members' is optional and must be a subset of the
+       list returned by getmembers().
+    """
+    import copy
+    import operator
+    from tarfile import ExtractError
+    directories = []
+
+    if members is None:
+        members = self
+
+    for tarinfo in members:
+        if tarinfo.isdir():
+            # Extract directories with a safe mode.
+            directories.append(tarinfo)
+            tarinfo = copy.copy(tarinfo)
+            tarinfo.mode = 448 # decimal for oct 0700
+        self.extract(tarinfo, path)
+
+    # Reverse sort directories.
+    if sys.version_info < (2, 4):
+        def sorter(dir1, dir2):
+            return cmp(dir1.name, dir2.name)
+        directories.sort(sorter)
+        directories.reverse()
+    else:
+        directories.sort(key=operator.attrgetter('name'), reverse=True)
+
+    # Set correct owner, mtime and filemode on directories.
+    for tarinfo in directories:
+        dirpath = os.path.join(path, tarinfo.name)
+        try:
+            self.chown(tarinfo, dirpath)
+            self.utime(tarinfo, dirpath)
+            self.chmod(tarinfo, dirpath)
+        except ExtractError:
+            e = sys.exc_info()[1]
+            if self.errorlevel > 1:
+                raise
+            else:
+                self._dbg(1, "tarfile: %s" % e)
+
+
+def main(argv, version=DEFAULT_VERSION):
+    """Install or upgrade setuptools and EasyInstall"""
+    tarball = download_setuptools()
+    _install(tarball)
+
+
+if __name__ == '__main__':
+    main(sys.argv[1:])
diff --git a/lib3/Mako-0.7.3/doc/_sources/caching.txt b/lib3/Mako-0.7.3/doc/_sources/caching.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/caching.txt
@@ -0,0 +1,393 @@
+.. _caching_toplevel:
+
+=======
+Caching
+=======
+
+Any template or component can be cached using the ``cache``
+argument to the ``<%page>``, ``<%def>`` or ``<%block>`` directives:
+
+.. sourcecode:: mako
+
+    <%page cached="True"/>
+
+    template text
+
+The above template, after being executed the first time, will
+store its content within a cache that by default is scoped
+within memory. Subsequent calls to the template's :meth:`~.Template.render`
+method will return content directly from the cache. When the
+:class:`.Template` object itself falls out of scope, its corresponding
+cache is garbage collected along with the template.
+
+By default, caching requires that the `Beaker <http://beaker.readthedocs.org/>`_ package be installed on the
+system, however the mechanism of caching can be customized to use
+any third party or user defined system -- see :ref:`cache_plugins`.
+
+In addition to being available on the ``<%page>`` tag, the caching flag and all
+its options can be used with the ``<%def>`` tag as well:
+
+.. sourcecode:: mako
+
+    <%def name="mycomp" cached="True" cache_timeout="60">
+        other text
+    </%def>
+
+... and equivalently with the ``<%block>`` tag, anonymous or named:
+
+.. sourcecode:: mako
+
+    <%block cached="True" cache_timeout="60">
+        other text
+    </%block>
+
+Cache Arguments
+===============
+
+Mako has two cache arguments available on tags that are
+available in all cases.   The rest of the arguments
+available are specific to a backend.
+
+The two generic tags arguments are:
+
+* ``cached="True"`` - enable caching for this ``<%page>``,
+  ``<%def>``, or ``<%block>``.
+* ``cache_key`` - the "key" used to uniquely identify this content
+  in the cache.   Usually, this key is chosen automatically
+  based on the name of the rendering callable (i.e. ``body``
+  when used in ``<%page>``, the name of the def when using ``<%def>``,
+  the explicit or internally-generated name when using ``<%block>``).
+  Using the ``cache_key`` parameter, the key can be overridden
+  using a fixed or programmatically generated value.
+
+  For example, here's a page
+  that caches any page which inherits from it, based on the
+  filename of the calling template:
+
+  .. sourcecode:: mako
+
+     <%page cached="True" cache_key="${self.filename}"/>
+
+     ${next.body()}
+
+     ## rest of template
+
+On a :class:`.Template` or :class:`.TemplateLookup`, the
+caching can be configured using these arguments:
+
+* ``cache_enabled`` - Setting this
+  to ``False`` will disable all caching functionality
+  when the template renders.  Defaults to ``True``.
+  e.g.:
+
+  .. sourcecode:: python
+
+      lookup = TemplateLookup(
+                      directories='/path/to/templates',
+                      cache_enabled = False
+                      )
+
+* ``cache_impl`` - The string name of the cache backend
+  to use.   This defaults to ``'beaker'``, which has historically
+  been the only cache backend supported by Mako.
+
+  .. versionadded:: 0.6.0
+
+  For example, here's how to use the upcoming
+  `dogpile.cache <http://dogpilecache.readthedocs.org>`_
+  backend:
+
+  .. sourcecode:: python
+
+      lookup = TemplateLookup(
+                      directories='/path/to/templates',
+                      cache_impl = 'dogpile.cache',
+                      cache_args = {'regions':my_dogpile_regions}
+                      )
+
+* ``cache_args`` - A dictionary of cache parameters that
+  will be consumed by the cache backend.   See
+  :ref:`beaker_backend` for examples.
+
+  .. versionadded:: 0.6.0
+
+Backend-Specific Cache Arguments
+--------------------------------
+
+The ``<%page>``, ``<%def>``, and ``<%block>`` tags
+accept any named argument that starts with the prefix ``"cache_"``.
+Those arguments are then packaged up and passed along to the
+underlying caching implementation, minus the ``"cache_"`` prefix.
+
+The actual arguments understood are determined by the backend.
+
+* :ref:`beaker_backend` - Includes arguments understood by
+  Beaker.
+* :ref:`dogpile.cache_backend` - Includes arguments understood by
+  dogpile.cache.
+
+.. _beaker_backend:
+
+Using the Beaker Cache Backend
+------------------------------
+
+When using Beaker, new implementations will want to make usage
+of **cache regions** so that cache configurations can be maintained
+externally to templates.  These configurations live under
+named "regions" that can be referred to within templates themselves.
+
+.. versionadded:: 0.6.0
+   Support for Beaker cache regions.
+
+For example, suppose we would like two regions.  One is a "short term"
+region that will store content in a memory-based dictionary,
+expiring after 60 seconds.   The other is a Memcached region,
+where values should expire in five minutes.   To configure
+our :class:`.TemplateLookup`, first we get a handle to a
+:class:`beaker.cache.CacheManager`:
+
+.. sourcecode:: python
+
+    from beaker.cache import CacheManager
+
+    manager = CacheManager(cache_regions={
+        'short_term':{
+            'type': 'memory',
+            'expire': 60
+        },
+        'long_term':{
+            'type': 'ext:memcached',
+            'url': '127.0.0.1:11211',
+            'expire': 300
+        }
+    })
+
+    lookup = TemplateLookup(
+                    directories=['/path/to/templates'],
+                    module_directory='/path/to/modules',
+                    cache_impl='beaker',
+                    cache_args={
+                        'manager':manager
+                    }
+            )
+
+Our templates can then opt to cache data in one of either region,
+using the ``cache_region`` argument.   Such as using ``short_term``
+at the ``<%page>`` level:
+
+.. sourcecode:: mako
+
+    <%page cached="True" cache_region="short_term">
+
+    ## ...
+
+Or, ``long_term`` at the ``<%block>`` level:
+
+.. sourcecode:: mako
+
+    <%block name="header" cached="True" cache_region="long_term">
+        other text
+    </%block>
+
+The Beaker backend also works without regions.   There are a
+variety of arguments that can be passed to the ``cache_args``
+dictionary, which are also allowable in templates via the
+``<%page>``, ``<%block>``,
+and ``<%def>`` tags specific to those sections.   The values
+given override those specified at the  :class:`.TemplateLookup`
+or :class:`.Template` level.
+
+With the possible exception
+of ``cache_timeout``, these arguments are probably better off
+staying at the template configuration level.  Each argument
+specified as ``cache_XYZ`` in a template tag is specified
+without the ``cache_`` prefix in the ``cache_args`` dictionary:
+
+* ``cache_timeout`` - number of seconds in which to invalidate the
+  cached data.  After this timeout, the content is re-generated
+  on the next call.  Available as ``timeout`` in the ``cache_args``
+  dictionary.
+* ``cache_type`` - type of caching. ``'memory'``, ``'file'``, ``'dbm'``, or
+  ``'ext:memcached'`` (note that  the string ``memcached`` is
+  also accepted by the dogpile.cache Mako plugin, though not by Beaker itself).
+  Available as ``type`` in the ``cache_args`` dictionary.
+* ``cache_url`` - (only used for ``memcached`` but required) a single
+  IP address or a semi-colon separated list of IP address of
+  memcache servers to use.  Available as ``url`` in the ``cache_args``
+  dictionary.
+* ``cache_dir`` - in the case of the ``'file'`` and ``'dbm'`` cache types,
+  this is the filesystem directory with which to store data
+  files. If this option is not present, the value of
+  ``module_directory`` is used (i.e. the directory where compiled
+  template modules are stored). If neither option is available
+  an exception is thrown.  Available as ``dir`` in the
+  ``cache_args`` dictionary.
+
+.. _dogpile.cache_backend:
+
+Using the dogpile.cache Backend
+-------------------------------
+
+`dogpile.cache`_ is a new replacement for Beaker.   It provides
+a modernized, slimmed down interface and is generally easier to use
+than Beaker.   As of this writing it has not yet been released.  dogpile.cache
+includes its own Mako cache plugin -- see :mod:`dogpile.cache.plugins.mako_cache` in the
+dogpile.cache documentation.
+
+Programmatic Cache Access
+=========================
+
+The :class:`.Template`, as well as any template-derived :class:`.Namespace`, has
+an accessor called ``cache`` which returns the :class:`.Cache` object
+for that template. This object is a facade on top of the underlying
+:class:`.CacheImpl` object, and provides some very rudimental
+capabilities, such as the ability to get and put arbitrary
+values:
+
+.. sourcecode:: mako
+
+    <%
+        local.cache.set("somekey", type="memory", "somevalue")
+    %>
+
+Above, the cache associated with the ``local`` namespace is
+accessed and a key is placed within a memory cache.
+
+More commonly, the ``cache`` object is used to invalidate cached
+sections programmatically:
+
+.. sourcecode:: python
+
+    template = lookup.get_template('/sometemplate.html')
+
+    # invalidate the "body" of the template
+    template.cache.invalidate_body()
+
+    # invalidate an individual def
+    template.cache.invalidate_def('somedef')
+
+    # invalidate an arbitrary key
+    template.cache.invalidate('somekey')
+
+You can access any special method or attribute of the :class:`.CacheImpl`
+itself using the :attr:`impl <.Cache.impl>` attribute:
+
+.. sourcecode:: python
+
+    template.cache.impl.do_something_special()
+
+Note that using implementation-specific methods will mean you can't
+swap in a different kind of :class:`.CacheImpl` implementation at a
+later time.
+
+.. _cache_plugins:
+
+Cache Plugins
+=============
+
+The mechanism used by caching can be plugged in
+using a :class:`.CacheImpl` subclass.    This class implements
+the rudimental methods Mako needs to implement the caching
+API.   Mako includes the :class:`.BeakerCacheImpl` class to
+provide the default implementation.  A :class:`.CacheImpl` class
+is acquired by Mako using a ``pkg_resources`` entrypoint, using
+the name given as the ``cache_impl`` argument to :class:`.Template`
+or :class:`.TemplateLookup`.    This entry point can be
+installed via the standard `setuptools`/``setup()`` procedure, underneath
+the `EntryPoint` group named ``"mako.cache"``.  It can also be
+installed at runtime via a convenience installer :func:`.register_plugin`
+which accomplishes essentially the same task.
+
+An example plugin that implements a local dictionary cache:
+
+.. sourcecode:: python
+
+    from mako.cache import Cacheimpl, register_plugin
+
+    class SimpleCacheImpl(CacheImpl):
+        def __init__(self, cache):
+            super(SimpleCacheImpl, self).__init__(cache)
+            self._cache = {}
+
+        def get_or_create(self, key, creation_function, **kw):
+            if key in self._cache:
+                return self._cache[key]
+            else:
+                self._cache[key] = value = creation_function()
+                return value
+
+        def set(self, key, value, **kwargs):
+            self._cache[key] = value
+
+        def get(self, key, **kwargs):
+            return self._cache.get(key)
+
+        def invalidate(self, key, **kwargs):
+            self._cache.pop(key, None)
+
+    # optional - register the class locally
+    register_plugin("simple", __name__, "SimpleCacheImpl")
+
+Enabling the above plugin in a template would look like:
+
+.. sourcecode:: python
+
+    t = Template("mytemplate",
+                 file="mytemplate.html",
+                 cache_impl='simple')
+
+Guidelines for Writing Cache Plugins
+------------------------------------
+
+* The :class:`.CacheImpl` is created on a per-:class:`.Template` basis.  The
+  class should ensure that only data for the parent :class:`.Template` is
+  persisted or returned by the cache methods.    The actual :class:`.Template`
+  is available via the ``self.cache.template`` attribute.   The ``self.cache.id``
+  attribute, which is essentially the unique modulename of the template, is
+  a good value to use in order to represent a unique namespace of keys specific
+  to the template.
+* Templates only use the :meth:`.CacheImpl.get_or_create()` method
+  in an implicit fashion.  The :meth:`.CacheImpl.set`,
+  :meth:`.CacheImpl.get`, and :meth:`.CacheImpl.invalidate` methods are
+  only used in response to direct programmatic access to the corresponding
+  methods on the :class:`.Cache` object.
+* :class:`.CacheImpl` will be accessed in a multithreaded fashion if the
+  :class:`.Template` itself is used multithreaded.  Care should be taken
+  to ensure caching implementations are threadsafe.
+* A library like `Dogpile <http://pypi.python.org/pypi/dogpile.core>`_, which
+  is a minimal locking system derived from Beaker, can be used to help
+  implement the :meth:`.CacheImpl.get_or_create` method in a threadsafe
+  way that can maximize effectiveness across multiple threads as well
+  as processes. :meth:`.CacheImpl.get_or_create` is the
+  key method used by templates.
+* All arguments passed to ``**kw`` come directly from the parameters
+  inside the ``<%def>``, ``<%block>``, or ``<%page>`` tags directly,
+  minus the ``"cache_"`` prefix, as strings, with the exception of
+  the argument ``cache_timeout``, which is passed to the plugin
+  as the name ``timeout`` with the value converted to an integer.
+  Arguments present in ``cache_args`` on :class:`.Template` or
+  :class:`.TemplateLookup` are passed directly, but are superseded
+  by those present in the most specific template tag.
+* The directory where :class:`.Template` places module files can
+  be acquired using the accessor ``self.cache.template.module_directory``.
+  This directory can be a good place to throw cache-related work
+  files, underneath a prefix like ``_my_cache_work`` so that name
+  conflicts with generated modules don't occur.
+
+API Reference
+=============
+
+.. autoclass:: mako.cache.Cache
+    :members:
+    :show-inheritance:
+
+.. autoclass:: mako.cache.CacheImpl
+    :members:
+    :show-inheritance:
+
+.. autofunction:: mako.cache.register_plugin
+
+.. autoclass:: mako.ext.beaker_cache.BeakerCacheImpl
+    :members:
+    :show-inheritance:
+
diff --git a/lib3/Mako-0.7.3/doc/_sources/defs.txt b/lib3/Mako-0.7.3/doc/_sources/defs.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/defs.txt
@@ -0,0 +1,622 @@
+.. _defs_toplevel:
+
+===============
+Defs and Blocks
+===============
+
+``<%def>`` and ``<%block>`` are two tags that both demarcate any block of text
+and/or code.   They both exist within generated Python as a callable function,
+i.e., a Python ``def``.   They differ in their scope and calling semantics.
+Whereas ``<%def>`` provides a construct that is very much like a named Python
+``def``, the ``<%block>`` is more layout oriented.
+
+Using Defs
+==========
+
+The ``<%def>`` tag requires a ``name`` attribute, where the ``name`` references
+a Python function signature:
+
+.. sourcecode:: mako
+
+    <%def name="hello()">
+        hello world
+    </%def>
+
+To invoke the ``<%def>``, it is normally called as an expression:
+
+.. sourcecode:: mako
+
+    the def:  ${hello()}
+
+If the ``<%def>`` is not nested inside of another ``<%def>``,
+it's known as a **top level def** and can be accessed anywhere in
+the template, including above where it was defined.
+
+All defs, top level or not, have access to the current
+contextual namespace in exactly the same way their containing
+template does. Suppose the template below is executed with the
+variables ``username`` and ``accountdata`` inside the context:
+
+.. sourcecode:: mako
+
+    Hello there ${username}, how are ya.  Lets see what your account says:
+
+    ${account()}
+
+    <%def name="account()">
+        Account for ${username}:<br/>
+
+        % for row in accountdata:
+            Value: ${row}<br/>
+        % endfor
+    </%def>
+
+The ``username`` and ``accountdata`` variables are present
+within the main template body as well as the body of the
+``account()`` def.
+
+Since defs are just Python functions, you can define and pass
+arguments to them as well:
+
+.. sourcecode:: mako
+
+    ${account(accountname='john')}
+
+    <%def name="account(accountname, type='regular')">
+        account name: ${accountname}, type: ${type}
+    </%def>
+
+When you declare an argument signature for your def, they are
+required to follow normal Python conventions (i.e., all
+arguments are required except keyword arguments with a default
+value). This is in contrast to using context-level variables,
+which evaluate to ``UNDEFINED`` if you reference a name that
+does not exist.
+
+Calling Defs from Other Files
+-----------------------------
+
+Top level ``<%def>``\ s are **exported** by your template's
+module, and can be called from the outside; including from other
+templates, as well as normal Python code. Calling a ``<%def>``
+from another template is something like using an ``<%include>``
+-- except you are calling a specific function within the
+template, not the whole template.
+
+The remote ``<%def>`` call is also a little bit like calling
+functions from other modules in Python. There is an "import"
+step to pull the names from another template into your own
+template; then the function or functions are available.
+
+To import another template, use the ``<%namespace>`` tag:
+
+.. sourcecode:: mako
+
+    <%namespace name="mystuff" file="mystuff.html"/>
+
+The above tag adds a local variable ``mystuff`` to the current
+scope.
+
+Then, just call the defs off of ``mystuff``:
+
+.. sourcecode:: mako
+
+    ${mystuff.somedef(x=5,y=7)}
+
+The ``<%namespace>`` tag also supports some of the other
+semantics of Python's ``import`` statement, including pulling
+names into the local variable space, or using ``*`` to represent
+all names, using the ``import`` attribute:
+
+.. sourcecode:: mako
+
+    <%namespace file="mystuff.html" import="foo, bar"/>
+
+This is just a quick intro to the concept of a **namespace**,
+which is a central Mako concept that has its own chapter in
+these docs. For more detail and examples, see
+:ref:`namespaces_toplevel`.
+
+Calling Defs Programmatically
+-----------------------------
+
+You can call defs programmatically from any :class:`.Template` object
+using the :meth:`~.Template.get_def()` method, which returns a :class:`.DefTemplate`
+object. This is a :class:`.Template` subclass which the parent
+:class:`.Template` creates, and is usable like any other template:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    template = Template("""
+        <%def name="hi(name)">
+            hi ${name}!
+        </%def>
+
+        <%def name="bye(name)">
+            bye ${name}!
+        </%def>
+    """)
+
+    print template.get_def("hi").render(name="ed")
+    print template.get_def("bye").render(name="ed")
+
+Defs within Defs
+----------------
+
+The def model follows regular Python rules for closures.
+Declaring ``<%def>`` inside another ``<%def>`` declares it
+within the parent's **enclosing scope**:
+
+.. sourcecode:: mako
+
+    <%def name="mydef()">
+        <%def name="subdef()">
+            a sub def
+        </%def>
+
+        i'm the def, and the subcomponent is ${subdef()}
+    </%def>
+
+Just like Python, names that exist outside the inner ``<%def>``
+exist inside it as well:
+
+.. sourcecode:: mako
+
+    <%
+        x = 12
+    %>
+    <%def name="outer()">
+        <%
+            y = 15
+        %>
+        <%def name="inner()">
+            inner, x is ${x}, y is ${y}
+        </%def>
+
+        outer, x is ${x}, y is ${y}
+    </%def>
+
+Assigning to a name inside of a def declares that name as local
+to the scope of that def (again, like Python itself). This means
+the following code will raise an error:
+
+.. sourcecode:: mako
+
+    <%
+        x = 10
+    %>
+    <%def name="somedef()">
+        ## error !
+        somedef, x is ${x}
+        <%
+            x = 27
+        %>
+    </%def>
+
+...because the assignment to ``x`` declares ``x`` as local to the
+scope of ``somedef``, rendering the "outer" version unreachable
+in the expression that tries to render it.
+
+.. _defs_with_content:
+
+Calling a Def with Embedded Content and/or Other Defs
+-----------------------------------------------------
+
+A flip-side to def within def is a def call with content. This
+is where you call a def, and at the same time declare a block of
+content (or multiple blocks) that can be used by the def being
+called. The main point of such a call is to create custom,
+nestable tags, just like any other template language's
+custom-tag creation system -- where the external tag controls the
+execution of the nested tags and can communicate state to them.
+Only with Mako, you don't have to use any external Python
+modules, you can define arbitrarily nestable tags right in your
+templates.
+
+To achieve this, the target def is invoked using the form
+``<%namepacename:defname>`` instead of the normal ``${}``
+syntax. This syntax, introduced in Mako 0.2.3, is functionally
+equivalent to another tag known as ``%call``, which takes the form
+``<%call expr='namespacename.defname(args)'>``. While ``%call``
+is available in all versions of Mako, the newer style is
+probably more familiar looking. The ``namespace`` portion of the
+call is the name of the **namespace** in which the def is
+defined -- in the most simple cases, this can be ``local`` or
+``self`` to reference the current template's namespace (the
+difference between ``local`` and ``self`` is one of inheritance
+-- see :ref:`namespaces_builtin` for details).
+
+When the target def is invoked, a variable ``caller`` is placed
+in its context which contains another namespace containing the
+body and other defs defined by the caller. The body itself is
+referenced by the method ``body()``. Below, we build a ``%def``
+that operates upon ``caller.body()`` to invoke the body of the
+custom tag:
+
+.. sourcecode:: mako
+
+    <%def name="buildtable()">
+        <table>
+            <tr><td>
+                ${caller.body()}
+            </td></tr>
+        </table>
+    </%def>
+
+    <%self:buildtable>
+        I am the table body.
+    </%self:buildtable>
+
+This produces the output (whitespace formatted):
+
+.. sourcecode:: html
+
+    <table>
+        <tr><td>
+            I am the table body.
+        </td></tr>
+    </table>
+
+Using the older ``%call`` syntax looks like:
+
+.. sourcecode:: mako
+
+    <%def name="buildtable()">
+        <table>
+            <tr><td>
+                ${caller.body()}
+            </td></tr>
+        </table>
+    </%def>
+
+    <%call expr="buildtable()">
+        I am the table body.
+    </%call>
+
+The ``body()`` can be executed multiple times or not at all.
+This means you can use def-call-with-content to build iterators,
+conditionals, etc:
+
+.. sourcecode:: mako
+
+    <%def name="lister(count)">
+        % for x in range(count):
+            ${caller.body()}
+        % endfor
+    </%def>
+
+    <%self:lister count="${3}">
+        hi
+    </%self:lister>
+
+Produces:
+
+.. sourcecode:: html
+
+    hi
+    hi
+    hi
+
+Notice above we pass ``3`` as a Python expression, so that it
+remains as an integer.
+
+A custom "conditional" tag:
+
+.. sourcecode:: mako
+
+    <%def name="conditional(expression)">
+        % if expression:
+            ${caller.body()}
+        % endif
+    </%def>
+
+    <%self:conditional expression="${4==4}">
+        i'm the result
+    </%self:conditional>
+
+Produces:
+
+.. sourcecode:: html
+
+    i'm the result
+
+But that's not all. The ``body()`` function also can handle
+arguments, which will augment the local namespace of the body
+callable. The caller must define the arguments which it expects
+to receive from its target def using the ``args`` attribute,
+which is a comma-separated list of argument names. Below, our
+``<%def>`` calls the ``body()`` of its caller, passing in an
+element of data from its argument:
+
+.. sourcecode:: mako
+
+    <%def name="layoutdata(somedata)">
+        <table>
+        % for item in somedata:
+            <tr>
+            % for col in item:
+                <td>${caller.body(col=col)}</td>
+            % endfor
+            </tr>
+        % endfor
+        </table>
+    </%def>
+
+    <%self:layoutdata somedata="${[[1,2,3],[4,5,6],[7,8,9]]}" args="col">\
+    Body data: ${col}\
+    </%self:layoutdata>
+
+Produces:
+
+.. sourcecode:: html
+
+    <table>
+        <tr>
+            <td>Body data: 1</td>
+            <td>Body data: 2</td>
+            <td>Body data: 3</td>
+        </tr>
+        <tr>
+            <td>Body data: 4</td>
+            <td>Body data: 5</td>
+            <td>Body data: 6</td>
+        </tr>
+        <tr>
+            <td>Body data: 7</td>
+            <td>Body data: 8</td>
+            <td>Body data: 9</td>
+        </tr>
+    </table>
+
+You don't have to stick to calling just the ``body()`` function.
+The caller can define any number of callables, allowing the
+``<%call>`` tag to produce whole layouts:
+
+.. sourcecode:: mako
+
+    <%def name="layout()">
+        ## a layout def
+        <div class="mainlayout">
+            <div class="header">
+                ${caller.header()}
+            </div>
+
+            <div class="sidebar">
+                ${caller.sidebar()}
+            </div>
+
+            <div class="content">
+                ${caller.body()}
+            </div>
+        </div>
+    </%def>
+
+    ## calls the layout def
+    <%self:layout>
+        <%def name="header()">
+            I am the header
+        </%def>
+        <%def name="sidebar()">
+            <ul>
+                <li>sidebar 1</li>
+                <li>sidebar 2</li>
+            </ul>
+        </%def>
+
+            this is the body
+    </%self:layout>
+
+The above layout would produce:
+
+.. sourcecode:: html
+
+    <div class="mainlayout">
+        <div class="header">
+        I am the header
+        </div>
+
+        <div class="sidebar">
+        <ul>
+            <li>sidebar 1</li>
+            <li>sidebar 2</li>
+        </ul>
+        </div>
+
+        <div class="content">
+        this is the body
+        </div>
+    </div>
+
+The number of things you can do with ``<%call>`` and/or the
+``<%namespacename:defname>`` calling syntax is enormous. You can
+create form widget libraries, such as an enclosing ``<FORM>``
+tag and nested HTML input elements, or portable wrapping schemes
+using ``<div>`` or other elements. You can create tags that
+interpret rows of data, such as from a database, providing the
+individual columns of each row to a ``body()`` callable which
+lays out the row any way it wants. Basically anything you'd do
+with a "custom tag" or tag library in some other system, Mako
+provides via ``<%def>`` tags and plain Python callables which are
+invoked via ``<%namespacename:defname>`` or ``<%call>``.
+
+.. _blocks:
+
+Using Blocks
+============
+
+The ``<%block>`` tag introduces some new twists on the
+``<%def>`` tag which make it more closely tailored towards layout.
+
+.. versionadded:: 0.4.1
+
+An example of a block:
+
+.. sourcecode:: mako
+
+    <html>
+        <body>
+            <%block>
+                this is a block.
+            </%block>
+        </body>
+    </html>
+
+In the above example, we define a simple block.  The block renders its content in the place
+that it's defined.  Since the block is called for us, it doesn't need a name and the above
+is referred to as an **anonymous block**.  So the output of the above template will be:
+
+.. sourcecode:: html
+
+    <html>
+        <body>
+                this is a block.
+        </body>
+    </html>
+
+So in fact the above block has absolutely no effect.  Its usefulness comes when we start
+using modifiers.  Such as, we can apply a filter to our block:
+
+.. sourcecode:: mako
+
+    <html>
+        <body>
+            <%block filter="h">
+                <html>this is some escaped html.</html>
+            </%block>
+        </body>
+    </html>
+
+or perhaps a caching directive:
+
+.. sourcecode:: mako
+
+    <html>
+        <body>
+            <%block cached="True" cache_timeout="60">
+                This content will be cached for 60 seconds.
+            </%block>
+        </body>
+    </html>
+
+Blocks also work in iterations, conditionals, just like defs:
+
+.. sourcecode:: mako
+
+    % if some_condition:
+        <%block>condition is met</%block>
+    % endif
+
+While the block renders at the point it is defined in the template,
+the underlying function is present in the generated Python code only
+once, so there's no issue with placing a block inside of a loop or
+similar. Anonymous blocks are defined as closures in the local
+rendering body, so have access to local variable scope:
+
+.. sourcecode:: mako
+
+    % for i in range(1, 4):
+        <%block>i is ${i}</%block>
+    % endfor
+
+Using Named Blocks
+------------------
+
+Possibly the more important area where blocks are useful is when we
+do actually give them names. Named blocks are tailored to behave
+somewhat closely to Jinja2's block tag, in that they define an area
+of a layout which can be overridden by an inheriting template. In
+sharp contrast to the ``<%def>`` tag, the name given to a block is
+global for the entire template regardless of how deeply it's nested:
+
+.. sourcecode:: mako
+
+    <html>
+    <%block name="header">
+        <head>
+            <title>
+                <%block name="title">Title</%block>
+            </title>
+        </head>
+    </%block>
+    <body>
+        ${next.body()}
+    </body>
+    </html>
+
+The above example has two named blocks "``header``" and "``title``", both of which can be referred to
+by an inheriting template. A detailed walkthrough of this usage can be found at :ref:`inheritance_toplevel`.
+
+Note above that named blocks don't have any argument declaration the way defs do. They still implement themselves
+as Python functions, however, so they can be invoked additional times beyond their initial definition:
+
+.. sourcecode:: mako
+
+    <div name="page">
+        <%block name="pagecontrol">
+            <a href="">previous page</a> |
+            <a href="">next page</a>
+        </%block>
+
+        <table>
+            ## some content
+        </table>
+
+        ${pagecontrol()}
+    </div>
+
+The content referenced by ``pagecontrol`` above will be rendered both above and below the ``<table>`` tags.
+
+To keep things sane, named blocks have restrictions that defs do not:
+
+* The ``<%block>`` declaration cannot have any argument signature.
+* The name of a ``<%block>`` can only be defined once in a template -- an error is raised if two blocks of the same
+  name occur anywhere in a single template, regardless of nesting.  A similar error is raised if a top level def
+  shares the same name as that of a block.
+* A named ``<%block>`` cannot be defined within a ``<%def>``, or inside the body of a "call", i.e.
+  ``<%call>`` or ``<%namespacename:defname>`` tag.  Anonymous blocks can, however.
+
+Using Page Arguments in Named Blocks
+------------------------------------
+
+A named block is very much like a top level def. It has a similar
+restriction to these types of defs in that arguments passed to the
+template via the ``<%page>`` tag aren't automatically available.
+Using arguments with the ``<%page>`` tag is described in the section
+:ref:`namespaces_body`, and refers to scenarios such as when the
+``body()`` method of a template is called from an inherited template passing
+arguments, or the template is invoked from an ``<%include>`` tag
+with arguments. To allow a named block to share the same arguments
+passed to the page, the ``args`` attribute can be used:
+
+.. sourcecode:: mako
+
+    <%page args="post"/>
+
+    <a name="${post.title}" />
+
+    <span class="post_prose">
+        <%block name="post_prose" args="post">
+            ${post.content}
+        </%block>
+    </span>
+
+Where above, if the template is called via a directive like
+``<%include file="post.mako" args="post=post" />``, the ``post``
+variable is available both in the main body as well as the
+``post_prose`` block.
+
+Similarly, the ``**pageargs`` variable is present, in named blocks only,
+for those arguments not explicit in the ``<%page>`` tag:
+
+.. sourcecode:: mako
+
+    <%block name="post_prose">
+        ${pageargs['post'].content}
+    </%block>
+
+The ``args`` attribute is only allowed with named blocks. With
+anonymous blocks, the Python function is always rendered in the same
+scope as the call itself, so anything available directly outside the
+anonymous block is available inside as well.
diff --git a/lib3/Mako-0.7.3/doc/_sources/filtering.txt b/lib3/Mako-0.7.3/doc/_sources/filtering.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/filtering.txt
@@ -0,0 +1,344 @@
+.. _filtering_toplevel:
+
+=======================
+Filtering and Buffering
+=======================
+
+Expression Filtering
+====================
+
+As described in the chapter :ref:`syntax_toplevel`, the "``|``" operator can be
+applied to a "``${}``" expression to apply escape filters to the
+output:
+
+.. sourcecode:: mako
+
+    ${"this is some text" | u}
+
+The above expression applies URL escaping to the expression, and
+produces ``this+is+some+text``.
+
+The built-in escape flags are:
+
+* ``u`` : URL escaping, provided by
+  ``urllib.quote_plus(string.encode('utf-8'))``
+* ``h`` : HTML escaping, provided by
+  ``markupsafe.escape(string)``
+
+  .. versionadded:: 0.3.4
+     Prior versions use ``cgi.escape(string, True)``.
+
+* ``x`` : XML escaping
+* ``trim`` : whitespace trimming, provided by ``string.strip()``
+* ``entity`` : produces HTML entity references for applicable
+  strings, derived from ``htmlentitydefs``
+* ``unicode`` (``str`` on Python 3): produces a Python unicode
+  string (this function is applied by default)
+* ``decode.<some encoding>``: decode input into a Python
+  unicode with the specified encoding
+* ``n`` : disable all default filtering; only filters specified
+  in the local expression tag will be applied.
+
+To apply more than one filter, separate them by a comma:
+
+.. sourcecode:: mako
+
+    ${" <tag>some value</tag> " | h,trim}
+
+The above produces ``<tag>some value</tag>``, with
+no leading or trailing whitespace. The HTML escaping function is
+applied first, the "trim" function second.
+
+Naturally, you can make your own filters too. A filter is just a
+Python function that accepts a single string argument, and
+returns the filtered result. The expressions after the ``|``
+operator draw upon the local namespace of the template in which
+they appear, meaning you can define escaping functions locally:
+
+.. sourcecode:: mako
+
+    <%!
+        def myescape(text):
+            return "<TAG>" + text + "</TAG>"
+    %>
+
+    Here's some tagged text: ${"text" | myescape}
+
+Or from any Python module:
+
+.. sourcecode:: mako
+
+    <%!
+        import myfilters
+    %>
+
+    Here's some tagged text: ${"text" | myfilters.tagfilter}
+
+A page can apply a default set of filters to all expression tags
+using the ``expression_filter`` argument to the ``%page`` tag:
+
+.. sourcecode:: mako
+
+    <%page expression_filter="h"/>
+
+    Escaped text:  ${"<html>some html</html>"}
+
+Result:
+
+.. sourcecode:: html
+
+    Escaped text: <html>some html</html>
+
+.. _filtering_default_filters:
+
+The ``default_filters`` Argument
+--------------------------------
+
+In addition to the ``expression_filter`` argument, the
+``default_filters`` argument to both :class:`.Template` and
+:class:`.TemplateLookup` can specify filtering for all expression tags
+at the programmatic level. This array-based argument, when given
+its default argument of ``None``, will be internally set to
+``["unicode"]`` (or ``["str"]`` on Python 3), except when
+``disable_unicode=True`` is set in which case it defaults to
+``["str"]``:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], default_filters=['unicode'])
+
+To replace the usual ``unicode``/``str`` function with a
+specific encoding, the ``decode`` filter can be substituted:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], default_filters=['decode.utf8'])
+
+To disable ``default_filters`` entirely, set it to an empty
+list:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], default_filters=[])
+
+Any string name can be added to ``default_filters`` where it
+will be added to all expressions as a filter. The filters are
+applied from left to right, meaning the leftmost filter is
+applied first.
+
+.. sourcecode:: python
+
+    t = Template(templatetext, default_filters=['unicode', 'myfilter'])
+
+To ease the usage of ``default_filters`` with custom filters,
+you can also add imports (or other code) to all templates using
+the ``imports`` argument:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'],
+                       default_filters=['unicode', 'myfilter'],
+                       imports=['from mypackage import myfilter'])
+
+The above will generate templates something like this:
+
+.. sourcecode:: python
+
+    # ....
+    from mypackage import myfilter
+
+    def render_body(context):
+        context.write(myfilter(unicode("some text")))
+
+Turning off Filtering with the ``n`` Filter
+-------------------------------------------
+
+In all cases the special ``n`` filter, used locally within an
+expression, will **disable** all filters declared in the
+``<%page>`` tag as well as in ``default_filters``. Such as:
+
+.. sourcecode:: mako
+
+    ${'myexpression' | n}
+
+will render ``myexpression`` with no filtering of any kind, and:
+
+.. sourcecode:: mako
+
+    ${'myexpression' | n,trim}
+
+will render ``myexpression`` using the ``trim`` filter only.
+
+Filtering Defs and Blocks
+=========================
+
+The ``%def`` and ``%block`` tags have an argument called ``filter`` which will apply the
+given list of filter functions to the output of the ``%def``:
+
+.. sourcecode:: mako
+
+    <%def name="foo()" filter="h, trim">
+        <b>this is bold</b>
+    </%def>
+
+When the ``filter`` attribute is applied to a def as above, the def
+is automatically **buffered** as well. This is described next.
+
+Buffering
+=========
+
+One of Mako's central design goals is speed. To this end, all of
+the textual content within a template and its various callables
+is by default piped directly to the single buffer that is stored
+within the :class:`.Context` object. While this normally is easy to
+miss, it has certain side effects. The main one is that when you
+call a def using the normal expression syntax, i.e.
+``${somedef()}``, it may appear that the return value of the
+function is the content it produced, which is then delivered to
+your template just like any other expression substitution,
+except that normally, this is not the case; the return value of
+``${somedef()}`` is simply the empty string ``''``. By the time
+you receive this empty string, the output of ``somedef()`` has
+been sent to the underlying buffer.
+
+You may not want this effect, if for example you are doing
+something like this:
+
+.. sourcecode:: mako
+
+    ${" results " + somedef() + " more results "}
+
+If the ``somedef()`` function produced the content "``somedef's
+results``", the above template would produce this output:
+
+.. sourcecode:: html
+
+    somedef's results results more results
+
+This is because ``somedef()`` fully executes before the
+expression returns the results of its concatenation; the
+concatenation in turn receives just the empty string as its
+middle expression.
+
+Mako provides two ways to work around this. One is by applying
+buffering to the ``%def`` itself:
+
+.. sourcecode:: mako
+
+    <%def name="somedef()" buffered="True">
+        somedef's results
+    </%def>
+
+The above definition will generate code similar to this:
+
+.. sourcecode:: python
+
+    def somedef():
+        context.push_buffer()
+        try:
+            context.write("somedef's results")
+        finally:
+            buf = context.pop_buffer()
+        return buf.getvalue()
+
+So that the content of ``somedef()`` is sent to a second buffer,
+which is then popped off the stack and its value returned. The
+speed hit inherent in buffering the output of a def is also
+apparent.
+
+Note that the ``filter`` argument on ``%def`` also causes the def to
+be buffered. This is so that the final content of the ``%def`` can
+be delivered to the escaping function in one batch, which
+reduces method calls and also produces more deterministic
+behavior for the filtering function itself, which can possibly
+be useful for a filtering function that wishes to apply a
+transformation to the text as a whole.
+
+The other way to buffer the output of a def or any Mako callable
+is by using the built-in ``capture`` function. This function
+performs an operation similar to the above buffering operation
+except it is specified by the caller.
+
+.. sourcecode:: mako
+
+    ${" results " + capture(somedef) + " more results "}
+
+Note that the first argument to the ``capture`` function is
+**the function itself**, not the result of calling it. This is
+because the ``capture`` function takes over the job of actually
+calling the target function, after setting up a buffered
+environment. To send arguments to the function, just send them
+to ``capture`` instead:
+
+.. sourcecode:: mako
+
+    ${capture(somedef, 17, 'hi', use_paging=True)}
+
+The above call is equivalent to the unbuffered call:
+
+.. sourcecode:: mako
+
+    ${somedef(17, 'hi', use_paging=True)}
+
+Decorating
+==========
+
+.. versionadded:: 0.2.5
+
+Somewhat like a filter for a ``%def`` but more flexible, the ``decorator``
+argument to ``%def`` allows the creation of a function that will
+work in a similar manner to a Python decorator. The function can
+control whether or not the function executes. The original
+intent of this function is to allow the creation of custom cache
+logic, but there may be other uses as well.
+
+``decorator`` is intended to be used with a regular Python
+function, such as one defined in a library module. Here we'll
+illustrate the python function defined in the template for
+simplicities' sake:
+
+.. sourcecode:: mako
+
+    <%!
+        def bar(fn):
+            def decorate(context, *args, **kw):
+                context.write("BAR")
+                fn(*args, **kw)
+                context.write("BAR")
+                return ''
+            return decorate
+    %>
+
+    <%def name="foo()" decorator="bar">
+        this is foo
+    </%def>
+
+    ${foo()}
+
+The above template will return, with more whitespace than this,
+``"BAR this is foo BAR"``. The function is the render callable
+itself (or possibly a wrapper around it), and by default will
+write to the context. To capture its output, use the :func:`.capture`
+callable in the ``mako.runtime`` module (available in templates
+as just ``runtime``):
+
+.. sourcecode:: mako
+
+    <%!
+        def bar(fn):
+            def decorate(context, *args, **kw):
+                return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR"
+            return decorate
+    %>
+
+    <%def name="foo()" decorator="bar">
+        this is foo
+    </%def>
+
+    ${foo()}
+
+The decorator can be used with top-level defs as well as nested
+defs, and blocks too. Note that when calling a top-level def from the
+:class:`.Template` API, i.e. ``template.get_def('somedef').render()``,
+the decorator has to write the output to the ``context``, i.e.
+as in the first example. The return value gets discarded.
diff --git a/lib3/Mako-0.7.3/doc/_sources/index.txt b/lib3/Mako-0.7.3/doc/_sources/index.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/index.txt
@@ -0,0 +1,22 @@
+Table of Contents
+=================
+
+.. toctree::
+    :maxdepth: 2
+
+    usage
+    syntax
+    defs
+    runtime
+    namespaces
+    inheritance
+    filtering
+    unicode
+    caching
+
+Indices and Tables
+------------------
+
+* :ref:`genindex`
+* :ref:`search`
+
diff --git a/lib3/Mako-0.7.3/doc/_sources/inheritance.txt b/lib3/Mako-0.7.3/doc/_sources/inheritance.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/inheritance.txt
@@ -0,0 +1,534 @@
+.. _inheritance_toplevel:
+
+===========
+Inheritance
+===========
+
+.. note::  Most of the inheritance examples here take advantage of a feature that's
+    new in Mako as of version 0.4.1 called the "block".  This tag is very similar to
+    the "def" tag but is more streamlined for usage with inheritance.  Note that
+    all of the examples here which use blocks can also use defs instead.  Contrasting
+    usages will be illustrated.
+
+Using template inheritance, two or more templates can organize
+themselves into an **inheritance chain**, where content and
+functions from all involved templates can be intermixed. The
+general paradigm of template inheritance is this: if a template
+``A`` inherits from template ``B``, then template ``A`` agrees
+to send the executional control to template ``B`` at runtime
+(``A`` is called the **inheriting** template). Template ``B``,
+the **inherited** template, then makes decisions as to what
+resources from ``A`` shall be executed.
+
+In practice, it looks like this. Here's a hypothetical inheriting
+template, ``index.html``:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="base.html"/>
+
+    <%block name="header">
+        this is some header content
+    </%block>
+
+    this is the body content.
+
+And ``base.html``, the inherited template:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                <%block name="header"/>
+            </div>
+
+            ${self.body()}
+
+            <div class="footer">
+                <%block name="footer">
+                    this is the footer
+                </%block>
+            </div>
+        </body>
+    </html>
+
+Here is a breakdown of the execution:
+
+#. When ``index.html`` is rendered, control immediately passes to
+   ``base.html``.
+#. ``base.html`` then renders the top part of an HTML document,
+   then invokes the ``<%block name="header">`` block.  It invokes the
+   underlying ``header()`` function off of a built-in namespace
+   called ``self`` (this namespace was first introduced in the
+   :doc:`Namespaces chapter <namespaces>` in :ref:`namespace_self`). Since
+   ``index.html`` is the topmost template and also defines a block
+   called ``header``, it's this ``header`` block that ultimately gets
+   executed -- instead of the one that's present in ``base.html``.
+#. Control comes back to ``base.html``. Some more HTML is
+   rendered.
+#. ``base.html`` executes ``self.body()``. The ``body()``
+   function on all template-based namespaces refers to the main
+   body of the template, therefore the main body of
+   ``index.html`` is rendered.
+#. When ``<%block name="header">`` is encountered in ``index.html`` 
+   during the ``self.body()`` call, a conditional is checked -- does the
+   current inherited template, i.e. ``base.html``, also define this block? If yes,
+   the ``<%block>`` is **not** executed here -- the inheritance
+   mechanism knows that the parent template is responsible for rendering
+   this block (and in fact it already has).  In other words a block
+   only renders in its *basemost scope*.
+#. Control comes back to ``base.html``. More HTML is rendered,
+   then the ``<%block name="footer">`` expression is invoked.
+#. The ``footer`` block is only defined in ``base.html``, so being
+   the topmost definition of ``footer``, it's the one that
+   executes. If ``index.html`` also specified ``footer``, then
+   its version would **override** that of the base.
+#. ``base.html`` finishes up rendering its HTML and the template
+   is complete, producing:
+
+   .. sourcecode:: html
+
+        <html>
+            <body>
+                <div class="header">
+                    this is some header content
+                </div>
+
+                this is the body content.
+
+                <div class="footer">
+                    this is the footer
+                </div>
+            </body>
+        </html>
+
+...and that is template inheritance in a nutshell. The main idea
+is that the methods that you call upon ``self`` always
+correspond to the topmost definition of that method. Very much
+the way ``self`` works in a Python class, even though Mako is
+not actually using Python class inheritance to implement this
+functionality. (Mako doesn't take the "inheritance" metaphor too
+seriously; while useful to setup some commonly recognized
+semantics, a textual template is not very much like an
+object-oriented class construct in practice).
+
+Nesting Blocks
+==============
+
+The named blocks defined in an inherited template can also be nested within
+other blocks.  The name given to each block is globally accessible via any inheriting
+template.  We can add a new block ``title`` to our ``header`` block:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                <%block name="header">
+                    <h2>
+                        <%block name="title"/>
+                    </h2>
+                </%block>
+            </div>
+
+            ${self.body()}
+
+            <div class="footer">
+                <%block name="footer">
+                    this is the footer
+                </%block>
+            </div>
+        </body>
+    </html>
+
+The inheriting template can name either or both of ``header`` and ``title``, separately
+or nested themselves:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="base.html"/>
+
+    <%block name="header">
+        this is some header content
+        ${parent.header()}
+    </%block>
+
+    <%block name="title">
+        this is the title
+    </%block>
+
+    this is the body content.
+
+Note when we overrode ``header``, we added an extra call ``${parent.header()}`` in order to invoke
+the parent's ``header`` block in addition to our own.  That's described in more detail below,
+in :ref:`parent_namespace`.
+
+Rendering a Named Block Multiple Times
+======================================
+
+Recall from the section :ref:`blocks` that a named block is just like a ``<%def>``,
+with some different usage rules.  We can call one of our named sections distinctly, for example
+a section that is used more than once, such as the title of a page:
+
+.. sourcecode:: mako
+
+    <html>
+        <head>
+            <title>${self.title()}</title>
+        </head>
+        <body>
+        <%block name="header">
+            <h2><%block name="title"/></h2>
+        </%block>
+        ${self.body()}
+        </body>
+    </html>
+
+Where above an inheriting template can define ``<%block name="title">`` just once, and it will be
+used in the base template both in the ``<title>`` section as well as the ``<h2>``.
+
+But what about Defs?
+====================
+
+The previous example used the ``<%block>`` tag to produce areas of content
+to be overridden.  Before Mako 0.4.1, there wasn't any such tag -- instead
+there was only the ``<%def>`` tag.   As it turns out, named blocks and defs are
+largely interchangeable.  The def simply doesn't call itself automatically,
+and has more open-ended naming and scoping rules that are more flexible and similar
+to Python itself, but less suited towards layout.  The first example from
+this chapter using defs would look like:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="base.html"/>
+
+    <%def name="header()">
+        this is some header content
+    </%def>
+
+    this is the body content.
+
+And ``base.html``, the inherited template:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                ${self.header()}
+            </div>
+
+            ${self.body()}
+
+            <div class="footer">
+                ${self.footer()}
+            </div>
+        </body>
+    </html>
+
+    <%def name="header()"/>
+    <%def name="footer()">
+        this is the footer
+    </%def>
+
+Above, we illustrate that defs differ from blocks in that their definition
+and invocation are defined in two separate places, instead of at once. You can *almost* do exactly what a
+block does if you put the two together:
+
+.. sourcecode:: mako
+
+    <div class="header">
+        <%def name="header()"></%def>${self.header()}
+    </div>
+
+The ``<%block>`` is obviously more streamlined than the ``<%def>`` for this kind
+of usage.  In addition,
+the above "inline" approach with ``<%def>`` does not work with nesting:
+
+.. sourcecode:: mako
+
+    <head>
+        <%def name="header()">
+            <title>
+            ## this won't work !
+            <%def name="title()">default title</%def>${self.title()}
+            </title>
+        </%def>${self.header()}
+    </head>
+
+Where above, the ``title()`` def, because it's a def within a def, is not part of the
+template's exported namespace and will not be part of ``self``.  If the inherited template
+did define its own ``title`` def at the top level, it would be called, but the "default title"
+above is not present at all on ``self`` no matter what.  For this to work as expected
+you'd instead need to say:
+
+.. sourcecode:: mako
+
+    <head>
+        <%def name="header()">
+            <title>
+            ${self.title()}
+            </title>
+        </%def>${self.header()}
+
+        <%def name="title()"/>
+    </head>
+
+That is, ``title`` is defined outside of any other defs so that it is in the ``self`` namespace.
+It works, but the definition needs to be potentially far away from the point of render.
+
+A named block is always placed in the ``self`` namespace, regardless of nesting,
+so this restriction is lifted:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <head>
+        <%block name="header">
+            <title>
+            <%block name="title"/>
+            </title>
+        </%block>
+    </head>
+
+The above template defines ``title`` inside of ``header``, and an inheriting template can define
+one or both in **any** configuration, nested inside each other or not, in order for them to be used:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="base.html"/>
+    <%block name="title">
+        the title
+    </%block>
+    <%block name="header">
+        the header
+    </%block>
+
+So while the ``<%block>`` tag lifts the restriction of nested blocks not being available externally,
+in order to achieve this it *adds* the restriction that all block names in a single template need
+to be globally unique within the template, and additionally that a ``<%block>`` can't be defined
+inside of a ``<%def>``. It's a more restricted tag suited towards a more specific use case than ``<%def>``.
+
+Using the ``next`` Namespace to Produce Content Wrapping
+========================================================
+
+Sometimes you have an inheritance chain that spans more than two
+templates. Or maybe you don't, but you'd like to build your
+system such that extra inherited templates can be inserted in
+the middle of a chain where they would be smoothly integrated.
+If each template wants to define its layout just within its main
+body, you can't just call ``self.body()`` to get at the
+inheriting template's body, since that is only the topmost body.
+To get at the body of the *next* template, you call upon the
+namespace ``next``, which is the namespace of the template
+**immediately following** the current template.
+
+Lets change the line in ``base.html`` which calls upon
+``self.body()`` to instead call upon ``next.body()``:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                <%block name="header"/>
+            </div>
+
+            ${next.body()}
+
+            <div class="footer">
+                <%block name="footer">
+                    this is the footer
+                </%block>
+            </div>
+        </body>
+    </html>
+
+
+Lets also add an intermediate template called ``layout.html``,
+which inherits from ``base.html``:
+
+.. sourcecode:: mako
+
+    ## layout.html
+    <%inherit file="base.html"/>
+    <ul>
+        <%block name="toolbar">
+            <li>selection 1</li>
+            <li>selection 2</li>
+            <li>selection 3</li>
+        </%block>
+    </ul>
+    <div class="mainlayout">
+        ${next.body()}
+    </div>
+
+And finally change ``index.html`` to inherit from
+``layout.html`` instead:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="layout.html"/>
+
+    ## .. rest of template
+
+In this setup, each call to ``next.body()`` will render the body
+of the next template in the inheritance chain (which can be
+written as ``base.html -> layout.html -> index.html``). Control
+is still first passed to the bottommost template ``base.html``,
+and ``self`` still references the topmost definition of any
+particular def.
+
+The output we get would be:
+
+.. sourcecode:: html
+
+    <html>
+        <body>
+            <div class="header">
+                this is some header content
+            </div>
+
+            <ul>
+                <li>selection 1</li>
+                <li>selection 2</li>
+                <li>selection 3</li>
+            </ul>
+
+            <div class="mainlayout">
+            this is the body content.
+            </div>
+
+            <div class="footer">
+                this is the footer
+            </div>
+        </body>
+    </html>
+
+So above, we have the ``<html>``, ``<body>`` and
+``header``/``footer`` layout of ``base.html``, we have the
+``<ul>`` and ``mainlayout`` section of ``layout.html``, and the
+main body of ``index.html`` as well as its overridden ``header``
+def. The ``layout.html`` template is inserted into the middle of
+the chain without ``base.html`` having to change anything.
+Without the ``next`` namespace, only the main body of
+``index.html`` could be used; there would be no way to call
+``layout.html``'s body content.
+
+.. _parent_namespace:
+
+Using the ``parent`` Namespace to Augment Defs
+==============================================
+
+Lets now look at the other inheritance-specific namespace, the
+opposite of ``next`` called ``parent``. ``parent`` is the
+namespace of the template **immediately preceding** the current
+template. What's useful about this namespace is that
+defs or blocks can call upon their overridden versions.
+This is not as hard as it sounds and
+is very much like using the ``super`` keyword in Python. Lets
+modify ``index.html`` to augment the list of selections provided
+by the ``toolbar`` function in ``layout.html``:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="layout.html"/>
+
+    <%block name="header">
+        this is some header content
+    </%block>
+
+    <%block name="toolbar">
+        ## call the parent's toolbar first
+        ${parent.toolbar()}
+        <li>selection 4</li>
+        <li>selection 5</li>
+    </%block>
+
+    this is the body content.
+
+Above, we implemented a ``toolbar()`` function, which is meant
+to override the definition of ``toolbar`` within the inherited
+template ``layout.html``. However, since we want the content
+from that of ``layout.html`` as well, we call it via the
+``parent`` namespace whenever we want it's content, in this case
+before we add our own selections. So the output for the whole
+thing is now:
+
+.. sourcecode:: html
+
+    <html>
+        <body>
+            <div class="header">
+                this is some header content
+            </div>
+
+            <ul>
+                <li>selection 1</li>
+                <li>selection 2</li>
+                <li>selection 3</li>
+                <li>selection 4</li>
+                <li>selection 5</li>
+            </ul>
+
+            <div class="mainlayout">
+            this is the body content.
+            </div>
+
+            <div class="footer">
+                this is the footer
+            </div>
+        </body>
+    </html>
+
+and you're now a template inheritance ninja!
+
+Inheritable Attributes
+======================
+
+The :attr:`attr <.Namespace.attr>` accessor of the :class:`.Namespace` object
+allows access to module level variables declared in a template. By accessing
+``self.attr``, you can access regular attributes from the
+inheritance chain as declared in ``<%! %>`` sections. Such as:
+
+.. sourcecode:: mako
+
+    <%!
+        class_ = "grey"
+    %>
+
+    <div class="${self.attr.class_}">
+        ${self.body()}
+    </div>
+
+If an inheriting template overrides ``class_`` to be
+``"white"``, as in:
+
+.. sourcecode:: mako
+
+    <%!
+        class_ = "white"
+    %>
+    <%inherit file="parent.html"/>
+
+    This is the body
+
+you'll get output like:
+
+.. sourcecode:: html
+
+    <div class="white">
+        This is the body
+    </div>
+
diff --git a/lib3/Mako-0.7.3/doc/_sources/namespaces.txt b/lib3/Mako-0.7.3/doc/_sources/namespaces.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/namespaces.txt
@@ -0,0 +1,349 @@
+.. _namespaces_toplevel:
+
+==========
+Namespaces
+==========
+
+Namespaces are used to organize groups of defs into
+categories, and also to "import" defs from other files.
+
+If the file ``components.html`` defines these two defs:
+
+.. sourcecode:: mako
+
+    ## components.html
+    <%def name="comp1()">
+        this is comp1
+    </%def>
+
+    <%def name="comp2(x)">
+        this is comp2, x is ${x}
+    </%def>
+
+you can make another file, for example ``index.html``, that
+pulls those two defs into a namespace called ``comp``:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%namespace name="comp" file="components.html"/>
+
+    Here's comp1:  ${comp.comp1()}
+    Here's comp2:  ${comp.comp2(x=5)}
+
+The ``comp`` variable above is an instance of
+:class:`.Namespace`, a **proxy object** which delivers
+method calls to the underlying template callable using the
+current context.
+
+``<%namespace>`` also provides an ``import`` attribute which can
+be used to pull the names into the local namespace, removing the
+need to call it via the "``.``" operator. When ``import`` is used, the
+``name`` attribute is optional.
+
+.. sourcecode:: mako
+
+    <%namespace file="components.html" import="comp1, comp2"/>
+
+    Heres comp1:  ${comp1()}
+    Heres comp2:  ${comp2(x=5)}
+
+``import`` also supports the "``*``" operator:
+
+.. sourcecode:: mako
+
+    <%namespace file="components.html" import="*"/>
+
+    Heres comp1:  ${comp1()}
+    Heres comp2:  ${comp2(x=5)}
+
+The names imported by the ``import`` attribute take precedence
+over any names that exist within the current context.
+
+.. note:: In current versions of Mako, usage of ``import='*'`` is
+   known to decrease performance of the template. This will be
+   fixed in a future release.
+
+The ``file`` argument allows expressions -- if looking for
+context variables, the ``context`` must be named explicitly:
+
+.. sourcecode:: mako
+
+    <%namespace name="dyn" file="${context['namespace_name']}"/>
+
+Ways to Call Namespaces
+=======================
+
+There are essentially four ways to call a function from a
+namespace.
+
+The "expression" format, as described previously. Namespaces are
+just Python objects with functions on them, and can be used in
+expressions like any other function:
+
+.. sourcecode:: mako
+
+    ${mynamespace.somefunction('some arg1', 'some arg2', arg3='some arg3', arg4='some arg4')}
+
+Synonymous with the "expression" format is the "custom tag"
+format, when a "closed" tag is used. This format, introduced in
+Mako 0.2.3, allows the usage of a "custom" Mako tag, with the
+function arguments passed in using named attributes:
+
+.. sourcecode:: mako
+
+    <%mynamespace:somefunction arg1="some arg1" arg2="some arg2" arg3="some arg3" arg4="some arg4"/>
+
+When using tags, the values of the arguments are taken as
+literal strings by default. To embed Python expressions as
+arguments, use the embedded expression format:
+
+.. sourcecode:: mako
+
+    <%mynamespace:somefunction arg1="${someobject.format()}" arg2="${somedef(5, 12)}"/>
+
+The "custom tag" format is intended mainly for namespace
+functions which recognize body content, which in Mako is known
+as a "def with embedded content":
+
+.. sourcecode:: mako
+
+    <%mynamespace:somefunction arg1="some argument" args="x, y">
+        Some record: ${x}, ${y}
+    </%mynamespace:somefunction>
+
+The "classic" way to call defs with embedded content is the ``<%call>`` tag:
+
+.. sourcecode:: mako
+
+    <%call expr="mynamespace.somefunction(arg1='some argument')" args="x, y">
+        Some record: ${x}, ${y}
+    </%call>
+
+For information on how to construct defs that embed content from
+the caller, see :ref:`defs_with_content`.
+
+.. _namespaces_python_modules:
+
+Namespaces from Regular Python Modules
+======================================
+
+Namespaces can also import regular Python functions from
+modules. These callables need to take at least one argument,
+``context``, an instance of :class:`.Context`. A module file 
+``some/module.py`` might contain the callable:
+
+.. sourcecode:: python
+
+    def my_tag(context):
+        context.write("hello world")
+        return ''
+
+A template can use this module via:
+
+.. sourcecode:: mako
+
+    <%namespace name="hw" module="some.module"/>
+
+    ${hw.my_tag()}
+
+Note that the ``context`` argument is not needed in the call;
+the :class:`.Namespace` tag creates a locally-scoped callable which
+takes care of it. The ``return ''`` is so that the def does not
+dump a ``None`` into the output stream -- the return value of any
+def is rendered after the def completes, in addition to whatever
+was passed to :meth:`.Context.write` within its body.
+
+If your def is to be called in an "embedded content" context,
+that is as described in :ref:`defs_with_content`, you should use
+the :func:`.supports_caller` decorator, which will ensure that Mako
+will ensure the correct "caller" variable is available when your
+def is called, supporting embedded content:
+
+.. sourcecode:: python
+
+    from mako.runtime import supports_caller
+
+    @supports_caller
+    def my_tag(context):
+        context.write("<div>")
+        context['caller'].body()
+        context.write("</div>")
+        return ''
+
+Capturing of output is available as well, using the
+outside-of-templates version of the :func:`.capture` function,
+which accepts the "context" as its first argument:
+
+.. sourcecode:: python
+
+    from mako.runtime import supports_caller, capture
+
+    @supports_caller
+    def my_tag(context):
+        return "<div>%s</div>" % \
+                capture(context, context['caller'].body, x="foo", y="bar")
+
+Declaring Defs in Namespaces
+============================
+
+The ``<%namespace>`` tag supports the definition of ``<%def>``\ s
+directly inside the tag. These defs become part of the namespace
+like any other function, and will override the definitions
+pulled in from a remote template or module:
+
+.. sourcecode:: mako
+
+    ## define a namespace
+    <%namespace name="stuff">
+        <%def name="comp1()">
+            comp1
+        </%def>
+    </%namespace>
+
+    ## then call it
+    ${stuff.comp1()}
+
+.. _namespaces_body:
+
+The ``body()`` Method
+=====================
+
+Every namespace that is generated from a template contains a
+method called ``body()``. This method corresponds to the main
+body of the template, and plays its most important roles when
+using inheritance relationships as well as
+def-calls-with-content.
+
+Since the ``body()`` method is available from a namespace just
+like all the other defs defined in a template, what happens if
+you send arguments to it? By default, the ``body()`` method
+accepts no positional arguments, and for usefulness in
+inheritance scenarios will by default dump all keyword arguments
+into a dictionary called ``pageargs``. But if you actually want
+to get at the keyword arguments, Mako recommends you define your
+own argument signature explicitly. You do this via using the
+``<%page>`` tag:
+
+.. sourcecode:: mako
+
+    <%page args="x, y, someval=8, scope='foo', **kwargs"/>
+
+A template which defines the above signature requires that the
+variables ``x`` and ``y`` are defined, defines default values
+for ``someval`` and ``scope``, and sets up ``**kwargs`` to
+receive all other keyword arguments. If ``**kwargs`` or similar
+is not present, the argument ``**pageargs`` gets tacked on by
+Mako. When the template is called as a top-level template (i.e.
+via :meth:`~.Template.render`) or via the ``<%include>`` tag, the
+values for these arguments will be pulled from the ``Context``.
+In all other cases, i.e. via calling the ``body()`` method, the
+arguments are taken as ordinary arguments from the method call.
+So above, the body might be called as:
+
+.. sourcecode:: mako
+
+    ${self.body(5, y=10, someval=15, delta=7)}
+
+The :class:`.Context` object also supplies a :attr:`~.Context.kwargs` accessor, for
+cases when you'd like to pass along whatever is in the context to
+a ``body()`` callable:
+
+.. sourcecode:: mako
+
+    ${next.body(**context.kwargs)}
+
+The usefulness of calls like the above become more apparent when
+one works with inheriting templates. For more information on
+this, as well as the meanings of the names ``self`` and
+``next``, see :ref:`inheritance_toplevel`.
+
+.. _namespaces_builtin:
+
+Built-in Namespaces
+===================
+
+The namespace is so great that Mako gives your template one (or
+two) for free. The names of these namespaces are ``local`` and
+``self``. Other built-in namespaces include ``parent`` and
+``next``, which are optional and are described in
+:ref:`inheritance_toplevel`.
+
+.. _namespace_local:
+
+``local``
+---------
+
+The ``local`` namespace is basically the namespace for the
+currently executing template. This means that all of the top
+level defs defined in your template, as well as your template's
+``body()`` function, are also available off of the ``local``
+namespace.
+
+The ``local`` namespace is also where properties like ``uri``,
+``filename``, and ``module`` and the ``get_namespace`` method
+can be particularly useful.
+
+.. _namespace_self:
+
+``self``
+--------
+
+The ``self`` namespace, in the case of a template that does not
+use inheritance, is synonymous with ``local``. If inheritance is
+used, then ``self`` references the topmost template in the
+inheritance chain, where it is most useful for providing the
+ultimate form of various "method" calls which may have been
+overridden at various points in an inheritance chain. See
+:ref:`inheritance_toplevel`.
+
+Inheritable Namespaces
+======================
+
+The ``<%namespace>`` tag includes an optional attribute
+``inheritable="True"``, which will cause the namespace to be
+attached to the ``self`` namespace. Since ``self`` is globally
+available throughout an inheritance chain (described in the next
+section), all the templates in an inheritance chain can get at
+the namespace imported in a super-template via ``self``.
+
+.. sourcecode:: mako
+
+    ## base.html
+    <%namespace name="foo" file="foo.html" inheritable="True"/>
+
+    ${next.body()}
+
+    ## somefile.html
+    <%inherit file="base.html"/>
+
+    ${self.foo.bar()}
+
+This allows a super-template to load a whole bunch of namespaces
+that its inheriting templates can get to, without them having to
+explicitly load those namespaces themselves.
+
+The ``import="*"`` part of the ``<%namespace>`` tag doesn't yet
+interact with the ``inheritable`` flag, so currently you have to
+use the explicit namespace name off of ``self``, followed by the
+desired function name. But more on this in a future release.
+
+API Reference
+=============
+
+.. autoclass:: mako.runtime.Namespace
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.runtime.TemplateNamespace
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.runtime.ModuleNamespace
+    :show-inheritance:
+    :members:
+ 
+.. autofunction:: mako.runtime.supports_caller
+
+.. autofunction:: mako.runtime.capture
+
diff --git a/lib3/Mako-0.7.3/doc/_sources/runtime.txt b/lib3/Mako-0.7.3/doc/_sources/runtime.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/runtime.txt
@@ -0,0 +1,448 @@
+.. _runtime_toplevel:
+
+============================
+The Mako Runtime Environment
+============================
+
+This section describes a little bit about the objects and
+built-in functions that are available in templates.
+
+.. _context:
+
+Context
+=======
+
+The :class:`.Context` is the central object that is created when
+a template is first executed, and is responsible for handling
+all communication with the outside world.  Within the template
+environment, it is available via the :ref:`reserved name <reserved_names>`
+``context``.  The :class:`.Context` includes two
+major components, one of which is the output buffer, which is a
+file-like object such as Python's ``StringIO`` or similar, and
+the other a dictionary of variables that can be freely
+referenced within a template; this dictionary is a combination
+of the arguments sent to the :meth:`~.Template.render` function and
+some built-in variables provided by Mako's runtime environment.
+
+The Buffer
+----------
+
+The buffer is stored within the :class:`.Context`, and writing
+to it is achieved by calling the :meth:`~.Context.write` method
+-- in a template this looks like ``context.write('some string')``.
+You usually don't need to care about this, as all text within a template, as
+well as all expressions provided by ``${}``, automatically send
+everything to this method. The cases you might want to be aware
+of its existence are if you are dealing with various
+filtering/buffering scenarios, which are described in
+:ref:`filtering_toplevel`, or if you want to programmatically
+send content to the output stream, such as within a ``<% %>``
+block.
+
+.. sourcecode:: mako
+
+    <%
+        context.write("some programmatic text")
+    %>
+
+The actual buffer may or may not be the original buffer sent to
+the :class:`.Context` object, as various filtering/caching
+scenarios may "push" a new buffer onto the context's underlying
+buffer stack. For this reason, just stick with
+``context.write()`` and content will always go to the topmost
+buffer.
+
+.. _context_vars:
+
+Context Variables
+-----------------
+
+When your template is compiled into a Python module, the body
+content is enclosed within a Python function called
+``render_body``. Other top-level defs defined in the template are
+defined within their own function bodies which are named after
+the def's name with the prefix ``render_`` (i.e. ``render_mydef``).
+One of the first things that happens within these functions is
+that all variable names that are referenced within the function
+which are not defined in some other way (i.e. such as via
+assignment, module level imports, etc.) are pulled from the
+:class:`.Context` object's dictionary of variables. This is how you're
+able to freely reference variable names in a template which
+automatically correspond to what was passed into the current
+:class:`.Context`.
+
+* **What happens if I reference a variable name that is not in
+  the current context?** - The value you get back is a special
+  value called ``UNDEFINED``, or if the ``strict_undefined=True`` flag
+  is used a ``NameError`` is raised. ``UNDEFINED`` is just a simple global
+  variable with the class :class:`mako.runtime.Undefined`. The
+  ``UNDEFINED`` object throws an error when you call ``str()`` on
+  it, which is what happens if you try to use it in an
+  expression.
+* **UNDEFINED makes it hard for me to find what name is missing** - An alternative
+  is to specify the option ``strict_undefined=True``
+  to the :class:`.Template` or :class:`.TemplateLookup`.  This will cause
+  any non-present variables to raise an immediate ``NameError``
+  which includes the name of the variable in its message
+  when :meth:`~.Template.render` is called -- ``UNDEFINED`` is not used.
+
+  .. versionadded:: 0.3.6
+
+* **Why not just return None?** Using ``UNDEFINED``, or
+  raising a ``NameError`` is more
+  explicit and allows differentiation between a value of ``None``
+  that was explicitly passed to the :class:`.Context` and a value that
+  wasn't present at all.
+* **Why raise an exception when you call str() on it ? Why not
+  just return a blank string?** - Mako tries to stick to the
+  Python philosophy of "explicit is better than implicit". In
+  this case, it's decided that the template author should be made
+  to specifically handle a missing value rather than
+  experiencing what may be a silent failure. Since ``UNDEFINED``
+  is a singleton object just like Python's ``True`` or ``False``,
+  you can use the ``is`` operator to check for it:
+
+  .. sourcecode:: mako
+
+        % if someval is UNDEFINED:
+            someval is: no value
+        % else:
+            someval is: ${someval}
+        % endif
+
+Another facet of the :class:`.Context` is that its dictionary of
+variables is **immutable**. Whatever is set when
+:meth:`~.Template.render` is called is what stays. Of course, since
+its Python, you can hack around this and change values in the
+context's internal dictionary, but this will probably will not
+work as well as you'd think. The reason for this is that Mako in
+many cases creates copies of the :class:`.Context` object, which
+get sent to various elements of the template and inheriting
+templates used in an execution. So changing the value in your
+local :class:`.Context` will not necessarily make that value
+available in other parts of the template's execution. Examples
+of where Mako creates copies of the :class:`.Context` include
+within top-level def calls from the main body of the template
+(the context is used to propagate locally assigned variables
+into the scope of defs; since in the template's body they appear
+as inlined functions, Mako tries to make them act that way), and
+within an inheritance chain (each template in an inheritance
+chain has a different notion of ``parent`` and ``next``, which
+are all stored in unique :class:`.Context` instances).
+
+* **So what if I want to set values that are global to everyone
+  within a template request?** - All you have to do is provide a
+  dictionary to your :class:`.Context` when the template first
+  runs, and everyone can just get/set variables from that. Lets
+  say its called ``attributes``.
+
+  Running the template looks like:
+
+  .. sourcecode:: python
+
+      output = template.render(attributes={})
+
+  Within a template, just reference the dictionary:
+
+  .. sourcecode:: mako
+
+      <%
+          attributes['foo'] = 'bar'
+      %>
+      'foo' attribute is: ${attributes['foo']}
+
+* **Why can't "attributes" be a built-in feature of the
+  Context?** - This is an area where Mako is trying to make as
+  few decisions about your application as it possibly can.
+  Perhaps you don't want your templates to use this technique of
+  assigning and sharing data, or perhaps you have a different
+  notion of the names and kinds of data structures that should
+  be passed around. Once again Mako would rather ask the user to
+  be explicit.
+
+Context Methods and Accessors
+-----------------------------
+
+Significant members of :class:`.Context` include:
+
+* ``context[key]`` / ``context.get(key, default=None)`` -
+  dictionary-like accessors for the context. Normally, any
+  variable you use in your template is automatically pulled from
+  the context if it isn't defined somewhere already. Use the
+  dictionary accessor and/or ``get`` method when you want a
+  variable that *is* already defined somewhere else, such as in
+  the local arguments sent to a ``%def`` call. If a key is not
+  present, like a dictionary it raises ``KeyError``.
+* ``keys()`` - all the names defined within this context.
+* ``kwargs`` - this returns a **copy** of the context's
+  dictionary of variables. This is useful when you want to
+  propagate the variables in the current context to a function
+  as keyword arguments, i.e.:
+
+  .. sourcecode:: mako
+
+        ${next.body(**context.kwargs)}
+
+* ``write(text)`` - write some text to the current output
+  stream.
+* ``lookup`` - returns the :class:`.TemplateLookup` instance that is
+  used for all file-lookups within the current execution (even
+  though individual :class:`.Template` instances can conceivably have
+  different instances of a :class:`.TemplateLookup`, only the
+  :class:`.TemplateLookup` of the originally-called :class:`.Template` gets
+  used in a particular execution).
+
+.. _loop_context:
+
+The Loop Context
+================
+
+Within ``% for`` blocks, the :ref:`reserved name<reserved_names>` ``loop``
+is available.  ``loop`` tracks the progress of
+the ``for`` loop and makes it easy to use the iteration state to control
+template behavior:
+
+.. sourcecode:: mako
+
+    <ul>
+    % for a in ("one", "two", "three"):
+        <li>Item ${loop.index}: ${a}</li>
+    % endfor
+    </ul>
+
+.. versionadded:: 0.7
+
+Iterations
+----------
+
+Regardless of the type of iterable you're looping over, ``loop`` always tracks
+the 0-indexed iteration count (available at ``loop.index``), its parity
+(through the ``loop.even`` and ``loop.odd`` bools), and ``loop.first``, a bool
+indicating whether the loop is on its first iteration.  If your iterable
+provides a ``__len__`` method, ``loop`` also provides access to
+a count of iterations remaining at ``loop.reverse_index`` and ``loop.last``,
+a bool indicating whether the loop is on its last iteration; accessing these
+without ``__len__`` will raise a ``TypeError``.
+
+Cycling
+-------
+
+Cycling is available regardless of whether the iterable you're using provides
+a ``__len__`` method.  Prior to Mako 0.7, you might have generated a simple
+zebra striped list using ``enumerate``:
+
+.. sourcecode:: mako
+
+    <ul>
+    % for i, item in enumerate(('spam', 'ham', 'eggs')):
+      <li class="${'odd' if i % 2 else 'even'}">${item}</li>
+    % endfor
+    </ul>
+
+With ``loop.cycle``, you get the same results with cleaner code and less prep work:
+
+.. sourcecode:: mako
+
+    <ul>
+    % for item in ('spam', 'ham', 'eggs'):
+      <li class="${loop.cycle('even', 'odd')}">${item}</li>
+    % endfor
+    </ul>
+
+Both approaches produce output like the following:
+
+.. sourcecode:: html
+
+    <ul>
+      <li class="even">spam</li>
+      <li class="odd">ham</li>
+      <li class="even">eggs</li>
+    </ul>
+
+Parent Loops
+------------
+
+Loop contexts can also be transparently nested, and the Mako runtime will do
+the right thing and manage the scope for you.  You can access the parent loop
+context through ``loop.parent``.
+
+This allows you to reach all the way back up through the loop stack by
+chaining ``parent`` attribute accesses, i.e. ``loop.parent.parent....`` as
+long as the stack depth isn't exceeded.  For example, you can use the parent
+loop to make a checkered table:
+
+.. sourcecode:: mako
+
+    <table>
+    % for consonant in 'pbj':
+      <tr>
+      % for vowel in 'iou':
+        <td class="${'black' if (loop.parent.even == loop.even) else 'red'}">
+          ${consonant + vowel}t
+        </td>
+      % endfor
+      </tr>
+    % endfor
+    </table>
+
+.. sourcecode:: html
+
+    <table>
+      <tr>
+        <td class="black">
+          pit
+        </td>
+        <td class="red">
+          pot
+        </td>
+        <td class="black">
+          put
+        </td>
+      </tr>
+      <tr>
+        <td class="red">
+          bit
+        </td>
+        <td class="black">
+          bot
+        </td>
+        <td class="red">
+          but
+        </td>
+      </tr>
+      <tr>
+        <td class="black">
+          jit
+        </td>
+        <td class="red">
+          jot
+        </td>
+        <td class="black">
+          jut
+        </td>
+      </tr>
+    </table>
+
+.. _migrating_loop:
+
+Migrating Legacy Templates that Use the Word "loop"
+---------------------------------------------------
+
+.. versionchanged:: 0.7
+   The ``loop`` name is now :ref:`reserved <reserved_names>` in Mako,
+   which means a template that refers to a variable named ``loop``
+   won't function correctly when used in Mako 0.7.
+
+To ease the transition for such systems, the feature can be disabled across the board for
+all templates, then re-enabled on a per-template basis for those templates which wish
+to make use of the new system.
+
+First, the ``enable_loop=False`` flag is passed to either the :class:`.TemplateLookup`
+or :class:`.Template` object in use:
+
+.. sourcecode:: python
+
+    lookup = TemplateLookup(directories=['/docs'], enable_loop=False)
+
+or:
+
+.. sourcecode:: python
+
+    template = Template("some template", enable_loop=False)
+
+An individual template can make usage of the feature when ``enable_loop`` is set to
+``False`` by switching it back on within the ``<%page>`` tag:
+
+.. sourcecode:: mako
+
+    <%page enable_loop="True"/>
+
+    % for i in collection:
+        ${i} ${loop.index}
+    % endfor
+
+Using the above scheme, it's safe to pass the name ``loop`` to the :meth:`.Template.render`
+method as well as to freely make usage of a variable named ``loop`` within a template, provided
+the ``<%page>`` tag doesn't override it.  New templates that want to use the ``loop`` context
+can then set up ``<%page enable_loop="True"/>`` to use the new feature without affecting
+old templates.
+
+All the Built-in Names
+======================
+
+A one-stop shop for all the names Mako defines. Most of these
+names are instances of :class:`.Namespace`, which are described
+in the next section, :ref:`namespaces_toplevel`. Also, most of
+these names other than ``context``, ``UNDEFINED``, and ``loop`` are
+also present *within* the :class:`.Context` itself.   The names
+``context``, ``loop`` and ``UNDEFINED`` themselves can't be passed
+to the context and can't be substituted -- see the section :ref:`reserved_names`.
+
+* ``context`` - this is the :class:`.Context` object, introduced
+  at :ref:`context`.
+* ``local`` - the namespace of the current template, described
+  in :ref:`namespaces_builtin`.
+* ``self`` - the namespace of the topmost template in an
+  inheritance chain (if any, otherwise the same as ``local``),
+  mostly described in :ref:`inheritance_toplevel`.
+* ``parent`` - the namespace of the parent template in an
+  inheritance chain (otherwise undefined); see
+  :ref:`inheritance_toplevel`.
+* ``next`` - the namespace of the next template in an
+  inheritance chain (otherwise undefined); see
+  :ref:`inheritance_toplevel`.
+* ``caller`` - a "mini" namespace created when using the
+  ``<%call>`` tag to define a "def call with content"; described
+  in :ref:`defs_with_content`.
+* ``loop`` - this provides access to :class:`.LoopContext` objects when
+  they are requested within ``% for`` loops, introduced at :ref:`loop_context`.
+* ``capture`` - a function that calls a given def and captures
+  its resulting content into a string, which is returned. Usage
+  is described in :ref:`filtering_toplevel`.
+* ``UNDEFINED`` - a global singleton that is applied to all
+  otherwise uninitialized template variables that were not
+  located within the :class:`.Context` when rendering began,
+  unless the :class:`.Template` flag ``strict_undefined``
+  is set to ``True``. ``UNDEFINED`` is
+  an instance of :class:`.Undefined`, and raises an
+  exception when its ``__str__()`` method is called.
+* ``pageargs`` - this is a dictionary which is present in a
+  template which does not define any ``**kwargs`` section in its
+  ``<%page>`` tag. All keyword arguments sent to the ``body()``
+  function of a template (when used via namespaces) go here by
+  default unless otherwise defined as a page argument. If this
+  makes no sense, it shouldn't; read the section
+  :ref:`namespaces_body`.
+
+.. _reserved_names:
+
+Reserved Names
+--------------
+
+Mako has a few names that are considered to be "reserved" and can't be used
+as variable names.
+
+.. versionchanged:: 0.7
+   Mako raises an error if these words are found passed to the template
+   as context arguments, whereas in previous versions they'd be silently
+   ignored or lead to other error messages.
+
+* ``context`` - see :ref:`context`.
+* ``UNDEFINED`` - see :ref:`context_vars`.
+* ``loop`` - see :ref:`loop_context`.  Note this can be disabled for legacy templates
+  via the ``enable_loop=False`` argument; see :ref:`migrating_loop`.
+
+API Reference
+=============
+
+.. autoclass:: mako.runtime.Context
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.runtime.LoopContext
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.runtime.Undefined
+    :show-inheritance:
+
diff --git a/lib3/Mako-0.7.3/doc/_sources/syntax.txt b/lib3/Mako-0.7.3/doc/_sources/syntax.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/syntax.txt
@@ -0,0 +1,469 @@
+.. _syntax_toplevel:
+
+======
+Syntax
+======
+
+A Mako template is parsed from a text stream containing any kind
+of content, XML, HTML, email text, etc. The template can further
+contain Mako-specific directives which represent variable and/or
+expression substitutions, control structures (i.e. conditionals
+and loops), server-side comments, full blocks of Python code, as
+well as various tags that offer additional functionality. All of
+these constructs compile into real Python code. This means that
+you can leverage the full power of Python in almost every aspect
+of a Mako template.
+
+Expression Substitution
+=======================
+
+The simplest expression is just a variable substitution. The
+syntax for this is the ``${}`` construct, which is inspired by
+Perl, Genshi, JSP EL, and others:
+
+.. sourcecode:: mako
+
+    this is x: ${x}
+
+Above, the string representation of ``x`` is applied to the
+template's output stream. If you're wondering where ``x`` comes
+from, it's usually from the :class:`.Context` supplied to the
+template's rendering function. If ``x`` was not supplied to the
+template and was not otherwise assigned locally, it evaluates to
+a special value ``UNDEFINED``. More on that later.
+
+The contents within the ``${}`` tag are evaluated by Python
+directly, so full expressions are OK:
+
+.. sourcecode:: mako
+
+    pythagorean theorem:  ${pow(x,2) + pow(y,2)}
+
+The results of the expression are evaluated into a string result
+in all cases before being rendered to the output stream, such as
+the above example where the expression produces a numeric
+result.
+
+Expression Escaping
+===================
+
+Mako includes a number of built-in escaping mechanisms,
+including HTML, URI and XML escaping, as well as a "trim"
+function. These escapes can be added to an expression
+substitution using the ``|`` operator:
+
+.. sourcecode:: mako
+
+    ${"this is some text" | u}
+
+The above expression applies URL escaping to the expression, and
+produces ``this+is+some+text``. The ``u`` name indicates URL
+escaping, whereas ``h`` represents HTML escaping, ``x``
+represents XML escaping, and ``trim`` applies a trim function.
+
+Read more about built-in filtering functions, including how to
+make your own filter functions, in :ref:`filtering_toplevel`.
+
+Control Structures
+==================
+
+A control structure refers to all those things that control the
+flow of a program -- conditionals (i.e. ``if``/``else``), loops (like
+``while`` and ``for``), as well as things like ``try``/``except``. In Mako,
+control structures are written using the ``%`` marker followed
+by a regular Python control expression, and are "closed" by
+using another ``%`` marker with the tag "``end<name>``", where
+"``<name>``" is the keyword of the expression:
+
+.. sourcecode:: mako
+
+    % if x==5:
+        this is some output
+    % endif
+
+The ``%`` can appear anywhere on the line as long as no text
+precedes it; indentation is not significant. The full range of
+Python "colon" expressions are allowed here, including
+``if``/``elif``/``else``, ``while``, ``for``, and even ``def``, although
+Mako has a built-in tag for defs which is more full-featured.
+
+.. sourcecode:: mako
+
+    % for a in ['one', 'two', 'three', 'four', 'five']:
+        % if a[0] == 't':
+        its two or three
+        % elif a[0] == 'f':
+        four/five
+        % else:
+        one
+        % endif
+    % endfor
+
+The ``%`` sign can also be "escaped", if you actually want to
+emit a percent sign as the first non whitespace character on a
+line, by escaping it as in ``%%``:
+
+.. sourcecode:: mako
+
+    %% some text
+
+        %% some more text
+
+The Loop Context
+----------------
+
+The **loop context** provides additional information about a loop
+while inside of a ``% for`` structure:
+
+.. sourcecode:: mako
+
+    <ul>
+    % for a in ("one", "two", "three"):
+        <li>Item ${loop.index}: ${a}</li>
+    % endfor
+    </ul>
+
+See :ref:`loop_context` for more information on this feature.
+
+.. versionadded:: 0.7
+
+Comments
+========
+
+Comments come in two varieties. The single line comment uses
+``##`` as the first non-space characters on a line:
+
+.. sourcecode:: mako
+
+    ## this is a comment.
+    ...text ...
+
+A multiline version exists using ``<%doc> ...text... </%doc>``:
+
+.. sourcecode:: mako
+
+    <%doc>
+        these are comments
+        more comments
+    </%doc>
+
+Newline Filters
+===============
+
+The backslash ("``\``") character, placed at the end of any
+line, will consume the newline character before continuing to
+the next line:
+
+.. sourcecode:: mako
+
+    here is a line that goes onto \
+    another line.
+
+The above text evaluates to:
+
+.. sourcecode:: text
+
+    here is a line that goes onto another line.
+
+Python Blocks
+=============
+
+Any arbitrary block of python can be dropped in using the ``<%
+%>`` tags:
+
+.. sourcecode:: mako
+
+    this is a template
+    <%
+        x = db.get_resource('foo')
+        y = [z.element for z in x if x.frobnizzle==5]
+    %>
+    % for elem in y:
+        element: ${elem}
+    % endfor
+
+Within ``<% %>``, you're writing a regular block of Python code.
+While the code can appear with an arbitrary level of preceding
+whitespace, it has to be consistently formatted with itself.
+Mako's compiler will adjust the block of Python to be consistent
+with the surrounding generated Python code.
+
+Module-level Blocks
+===================
+
+A variant on ``<% %>`` is the module-level code block, denoted
+by ``<%! %>``. Code within these tags is executed at the module
+level of the template, and not within the rendering function of
+the template. Therefore, this code does not have access to the
+template's context and is only executed when the template is
+loaded into memory (which can be only once per application, or
+more, depending on the runtime environment). Use the ``<%! %>``
+tags to declare your template's imports, as well as any
+pure-Python functions you might want to declare:
+
+.. sourcecode:: mako
+
+    <%!
+        import mylib
+        import re
+
+        def filter(text):
+            return re.sub(r'^@', '', text)
+    %>
+
+Any number of ``<%! %>`` blocks can be declared anywhere in a
+template; they will be rendered in the resulting module 
+in a single contiguous block above all render callables,
+in the order in which they appear in the source template.
+
+Tags
+====
+
+The rest of what Mako offers takes place in the form of tags.
+All tags use the same syntax, which is similar to an XML tag
+except that the first character of the tag name is a ``%``
+character. The tag is closed either by a contained slash
+character, or an explicit closing tag:
+
+.. sourcecode:: mako
+
+    <%include file="foo.txt"/>
+
+    <%def name="foo" buffered="True">
+        this is a def
+    </%def>
+
+All tags have a set of attributes which are defined for each
+tag. Some of these attributes are required. Also, many
+attributes support **evaluation**, meaning you can embed an
+expression (using ``${}``) inside the attribute text:
+
+.. sourcecode:: mako
+
+    <%include file="/foo/bar/${myfile}.txt"/>
+
+Whether or not an attribute accepts runtime evaluation depends
+on the type of tag and how that tag is compiled into the
+template. The best way to find out if you can stick an
+expression in is to try it! The lexer will tell you if it's not
+valid.
+
+Heres a quick summary of all the tags:
+
+``<%page>``
+-----------
+
+This tag defines general characteristics of the template,
+including caching arguments, and optional lists of arguments
+which the template expects when invoked.
+
+.. sourcecode:: mako
+
+    <%page args="x, y, z='default'"/>
+
+Or a page tag that defines caching characteristics:
+
+.. sourcecode:: mako
+
+    <%page cached="True" cache_type="memory"/>
+
+Currently, only one ``<%page>`` tag gets used per template, the
+rest get ignored. While this will be improved in a future
+release, for now make sure you have only one ``<%page>`` tag
+defined in your template, else you may not get the results you
+want. The details of what ``<%page>`` is used for are described
+further in :ref:`namespaces_body` as well as :ref:`caching_toplevel`.
+
+``<%include>``
+--------------
+
+A tag that is familiar from other template languages, ``%include``
+is a regular joe that just accepts a file argument and calls in
+the rendered result of that file:
+
+.. sourcecode:: mako
+
+    <%include file="header.html"/>
+
+        hello world
+
+    <%include file="footer.html"/>
+
+Include also accepts arguments which are available as ``<%page>`` arguments in the receiving template:
+
+.. sourcecode:: mako
+
+    <%include file="toolbar.html" args="current_section='members', username='ed'"/>
+
+``<%def>``
+----------
+
+The ``%def`` tag defines a Python function which contains a set
+of content, that can be called at some other point in the
+template. The basic idea is simple:
+
+.. sourcecode:: mako
+
+    <%def name="myfunc(x)">
+        this is myfunc, x is ${x}
+    </%def>
+
+    ${myfunc(7)}
+
+The ``%def`` tag is a lot more powerful than a plain Python ``def``, as
+the Mako compiler provides many extra services with ``%def`` that
+you wouldn't normally have, such as the ability to export defs
+as template "methods", automatic propagation of the current
+:class:`.Context`, buffering/filtering/caching flags, and def calls
+with content, which enable packages of defs to be sent as
+arguments to other def calls (not as hard as it sounds). Get the
+full deal on what ``%def`` can do in :ref:`defs_toplevel`.
+
+``<%block>``
+------------
+
+``%block`` is a tag that is close to a ``%def``,
+except executes itself immediately in its base-most scope,
+and can also be anonymous (i.e. with no name):
+
+.. sourcecode:: mako
+
+    <%block filter="h">
+        some <html> stuff.
+    </%block>
+
+Inspired by Jinja2 blocks, named blocks offer a syntactically pleasing way
+to do inheritance:
+
+.. sourcecode:: mako
+
+    <html>
+        <body>
+        <%block name="header">
+            <h2><%block name="title"/></h2>
+        </%block>
+        ${self.body()}
+        </body>
+    </html>
+
+Blocks are introduced in :ref:`blocks` and further described in :ref:`inheritance_toplevel`.
+
+.. versionadded:: 0.4.1
+
+``<%namespace>``
+----------------
+
+``%namespace`` is Mako's equivalent of Python's ``import``
+statement. It allows access to all the rendering functions and
+metadata of other template files, plain Python modules, as well
+as locally defined "packages" of functions.
+
+.. sourcecode:: mako
+
+    <%namespace file="functions.html" import="*"/>
+
+The underlying object generated by ``%namespace``, an instance of
+:class:`.mako.runtime.Namespace`, is a central construct used in
+templates to reference template-specific information such as the
+current URI, inheritance structures, and other things that are
+not as hard as they sound right here. Namespaces are described
+in :ref:`namespaces_toplevel`.
+
+``<%inherit>``
+--------------
+
+Inherit allows templates to arrange themselves in **inheritance
+chains**. This is a concept familiar in many other template
+languages.
+
+.. sourcecode:: mako
+
+    <%inherit file="base.html"/>
+
+When using the ``%inherit`` tag, control is passed to the topmost
+inherited template first, which then decides how to handle
+calling areas of content from its inheriting templates. Mako
+offers a lot of flexibility in this area, including dynamic
+inheritance, content wrapping, and polymorphic method calls.
+Check it out in :ref:`inheritance_toplevel`.
+
+``<%``\ nsname\ ``:``\ defname\ ``>``
+-------------------------------------
+
+Any user-defined "tag" can be created against
+a namespace by using a tag with a name of the form
+``<%<namespacename>:<defname>>``. The closed and open formats of such a
+tag are equivalent to an inline expression and the ``<%call>``
+tag, respectively.
+
+.. sourcecode:: mako
+
+    <%mynamespace:somedef param="some value">
+        this is the body
+    </%mynamespace:somedef>
+
+To create custom tags which accept a body, see
+:ref:`defs_with_content`.
+
+.. versionadded:: 0.2.3
+
+``<%call>``
+-----------
+
+The call tag is the "classic" form of a user-defined tag, and is
+roughly equivalent to the ``<%namespacename:defname>`` syntax
+described above. This tag is also described in :ref:`defs_with_content`.
+
+``<%doc>``
+----------
+
+The ``%doc`` tag handles multiline comments:
+
+.. sourcecode:: mako
+
+    <%doc>
+        these are comments
+        more comments
+    </%doc>
+
+Also the ``##`` symbol as the first non-space characters on a line can be used for single line comments.
+
+``<%text>``
+-----------
+
+This tag suspends the Mako lexer's normal parsing of Mako
+template directives, and returns its entire body contents as
+plain text. It is used pretty much to write documentation about
+Mako:
+
+.. sourcecode:: mako
+
+    <%text filter="h">
+        heres some fake mako ${syntax}
+        <%def name="x()">${x}</%def>
+    </%text>
+
+Returning Early from a Template
+===============================
+
+Sometimes you want to stop processing a template or ``<%def>``
+method in the middle and just use the text you've accumulated so
+far. You can use a ``return`` statement inside a Python
+block to do that.
+
+.. sourcecode:: mako
+
+    % if not len(records):
+        No records found.
+        <% return %>
+    % endif
+
+Or perhaps:
+
+.. sourcecode:: mako
+
+    <%
+        if not len(records):
+            return
+    %>
+
diff --git a/lib3/Mako-0.7.3/doc/_sources/unicode.txt b/lib3/Mako-0.7.3/doc/_sources/unicode.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/unicode.txt
@@ -0,0 +1,345 @@
+.. _unicode_toplevel:
+
+===================
+The Unicode Chapter
+===================
+
+The Python language supports two ways of representing what we
+know as "strings", i.e. series of characters. In Python 2, the
+two types are ``string`` and ``unicode``, and in Python 3 they are
+``bytes`` and ``string``. A key aspect of the Python 2 ``string`` and
+Python 3 ``bytes`` types are that they contain no information
+regarding what **encoding** the data is stored in. For this
+reason they were commonly referred to as **byte strings** on
+Python 2, and Python 3 makes this name more explicit. The
+origins of this come from Python's background of being developed
+before the Unicode standard was even available, back when
+strings were C-style strings and were just that, a series of
+bytes. Strings that had only values below 128 just happened to
+be **ASCII** strings and were printable on the console, whereas
+strings with values above 128 would produce all kinds of
+graphical characters and bells.
+
+Contrast the "byte-string" type with the "unicode/string" type.
+Objects of this latter type are created whenever you say something like
+``u"hello world"`` (or in Python 3, just ``"hello world"``). In this
+case, Python represents each character in the string internally
+using multiple bytes per character (something similar to
+UTF-16). What's important is that when using the
+``unicode``/``string`` type to store strings, Python knows the
+data's encoding; it's in its own internal format. Whereas when
+using the ``string``/``bytes`` type, it does not.
+
+When Python 2 attempts to treat a byte-string as a string, which
+means it's attempting to compare/parse its characters, to coerce
+it into another encoding, or to decode it to a unicode object,
+it has to guess what the encoding is. In this case, it will
+pretty much always guess the encoding as ``ascii``... and if the
+byte-string contains bytes above value 128, you'll get an error.
+Python 3 eliminates much of this confusion by just raising an
+error unconditionally if a byte-string is used in a
+character-aware context.
+
+There is one operation that Python *can* do with a non-ASCII
+byte-string, and it's a great source of confusion: it can dump the
+byte-string straight out to a stream or a file, with nary a care
+what the encoding is. To Python, this is pretty much like
+dumping any other kind of binary data (like an image) to a
+stream somewhere. In Python 2, it is common to see programs that
+embed all kinds of international characters and encodings into
+plain byte-strings (i.e. using ``"hello world"`` style literals)
+can fly right through their run, sending reams of strings out to
+wherever they are going, and the programmer, seeing the same
+output as was expressed in the input, is now under the illusion
+that his or her program is Unicode-compliant. In fact, their
+program has no unicode awareness whatsoever, and similarly has
+no ability to interact with libraries that *are* unicode aware.
+Python 3 makes this much less likely by defaulting to unicode as
+the storage format for strings.
+
+The "pass through encoded data" scheme is what template
+languages like Cheetah and earlier versions of Myghty do by
+default. Mako as of version 0.2 also supports this mode of
+operation when using Python 2, using the ``disable_unicode=True``
+flag. However, when using Mako in its default mode of
+unicode-aware, it requires explicitness when dealing with
+non-ASCII encodings. Additionally, if you ever need to handle
+unicode strings and other kinds of encoding conversions more
+intelligently, the usage of raw byte-strings quickly becomes a
+nightmare, since you are sending the Python interpreter
+collections of bytes for which it can make no intelligent
+decisions with regards to encoding. In Python 3 Mako only allows
+usage of native, unicode strings.
+
+In normal Mako operation, all parsed template constructs and
+output streams are handled internally as Python ``unicode``
+objects. It's only at the point of :meth:`~.Template.render` that this unicode
+stream may be rendered into whatever the desired output encoding
+is. The implication here is that the template developer must
+:ensure that :ref:`the encoding of all non-ASCII templates is explicit
+<set_template_file_encoding>` (still required in Python 3),
+that :ref:`all non-ASCII-encoded expressions are in one way or another
+converted to unicode <handling_non_ascii_expressions>`
+(not much of a burden in Python 3), and that :ref:`the output stream of the
+template is handled as a unicode stream being encoded to some
+encoding <defining_output_encoding>` (still required in Python 3).
+
+.. _set_template_file_encoding:
+
+Specifying the Encoding of a Template File
+==========================================
+
+This is the most basic encoding-related setting, and it is
+equivalent to Python's "magic encoding comment", as described in
+`pep-0263 <http://www.python.org/dev/peps/pep-0263/>`_. Any
+template that contains non-ASCII characters requires that this
+comment be present so that Mako can decode to unicode (and also
+make usage of Python's AST parsing services). Mako's lexer will
+use this encoding in order to convert the template source into a
+``unicode`` object before continuing its parsing:
+
+.. sourcecode:: mako
+
+    ## -*- coding: utf-8 -*-
+
+    Alors vous imaginez ma surprise, au lever du jour, quand 
+    une drôle de petite voix m’a réveillé. Elle disait:
+     « S’il vous plaît… dessine-moi un mouton! »
+
+For the picky, the regular expression used is derived from that
+of the above mentioned pep:
+
+.. sourcecode:: python
+
+    #.*coding[:=]\s*([-\w.]+).*\n
+
+The lexer will convert to unicode in all cases, so that if any
+characters exist in the template that are outside of the
+specified encoding (or the default of ``ascii``), the error will
+be immediate.
+
+As an alternative, the template encoding can be specified
+programmatically to either :class:`.Template` or :class:`.TemplateLookup` via
+the ``input_encoding`` parameter:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['./'], input_encoding='utf-8')
+
+The above will assume all located templates specify ``utf-8``
+encoding, unless the template itself contains its own magic
+encoding comment, which takes precedence.
+
+.. _handling_non_ascii_expressions:
+
+Handling Expressions
+====================
+
+The next area that encoding comes into play is in expression
+constructs. By default, Mako's treatment of an expression like
+this:
+
+.. sourcecode:: mako
+
+    ${"hello world"}
+
+looks something like this:
+
+.. sourcecode:: python
+
+    context.write(unicode("hello world"))
+
+In Python 3, it's just:
+
+.. sourcecode:: python
+
+    context.write(str("hello world"))
+
+That is, **the output of all expressions is run through the
+``unicode`` built-in**. This is the default setting, and can be
+modified to expect various encodings. The ``unicode`` step serves
+both the purpose of rendering non-string expressions into
+strings (such as integers or objects which contain ``__str()__``
+methods), and to ensure that the final output stream is
+constructed as a unicode object. The main implication of this is
+that **any raw byte-strings that contain an encoding other than
+ASCII must first be decoded to a Python unicode object**. It
+means you can't say this in Python 2:
+
+.. sourcecode:: mako
+
+    ${"voix m’a réveillé."}  ## error in Python 2!
+
+You must instead say this:
+
+.. sourcecode:: mako
+
+    ${u"voix m’a réveillé."}  ## OK !
+
+Similarly, if you are reading data from a file that is streaming
+bytes, or returning data from some object that is returning a
+Python byte-string containing a non-ASCII encoding, you have to
+explicitly decode to unicode first, such as:
+
+.. sourcecode:: mako
+
+    ${call_my_object().decode('utf-8')}
+
+Note that filehandles acquired by ``open()`` in Python 3 default
+to returning "text", that is the decoding is done for you. See
+Python 3's documentation for the ``open()`` built-in for details on
+this.
+
+If you want a certain encoding applied to *all* expressions,
+override the ``unicode`` builtin with the ``decode`` built-in at the
+:class:`.Template` or :class:`.TemplateLookup` level:
+
+.. sourcecode:: python
+
+    t = Template(templatetext, default_filters=['decode.utf8'])
+
+Note that the built-in ``decode`` object is slower than the
+``unicode`` function, since unlike ``unicode`` it's not a Python
+built-in, and it also checks the type of the incoming data to
+determine if string conversion is needed first.
+
+The ``default_filters`` argument can be used to entirely customize
+the filtering process of expressions. This argument is described
+in :ref:`filtering_default_filters`.
+
+.. _defining_output_encoding:
+
+Defining Output Encoding
+========================
+
+Now that we have a template which produces a pure unicode output
+stream, all the hard work is done. We can take the output and do
+anything with it.
+
+As stated in the :doc:`"Usage" chapter <usage>`, both :class:`.Template` and
+:class:`.TemplateLookup` accept ``output_encoding`` and ``encoding_errors``
+parameters which can be used to encode the output in any Python
+supported codec:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
+
+    mytemplate = mylookup.get_template("foo.txt")
+    print mytemplate.render()
+
+:meth:`~.Template.render` will return a ``bytes`` object in Python 3 if an output
+encoding is specified. By default it performs no encoding and
+returns a native string.
+
+:meth:`~.Template.render_unicode` will return the template output as a Python
+``unicode`` object (or ``string`` in Python 3):
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode()
+
+The above method disgards the output encoding keyword argument;
+you can encode yourself by saying:
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode().encode('utf-8', 'replace')
+
+Buffer Selection
+----------------
+
+Mako does play some games with the style of buffering used
+internally, to maximize performance. Since the buffer is by far
+the most heavily used object in a render operation, it's
+important!
+
+When calling :meth:`~.Template.render` on a template that does not specify any
+output encoding (i.e. it's ``ascii``), Python's ``cStringIO`` module,
+which cannot handle encoding of non-ASCII ``unicode`` objects
+(even though it can send raw byte-strings through), is used for
+buffering. Otherwise, a custom Mako class called
+``FastEncodingBuffer`` is used, which essentially is a super
+dumbed-down version of ``StringIO`` that gathers all strings into
+a list and uses ``u''.join(elements)`` to produce the final output
+-- it's markedly faster than ``StringIO``.
+
+.. _unicode_disabled:
+
+Saying to Heck with It: Disabling the Usage of Unicode Entirely
+===============================================================
+
+Some segments of Mako's userbase choose to make no usage of
+Unicode whatsoever, and instead would prefer the "pass through"
+approach; all string expressions in their templates return
+encoded byte-strings, and they would like these strings to pass
+right through. The only advantage to this approach is that
+templates need not use ``u""`` for literal strings; there's an
+arguable speed improvement as well since raw byte-strings
+generally perform slightly faster than unicode objects in
+Python. For these users, assuming they're sticking with Python
+2, they can hit the ``disable_unicode=True`` flag as so:
+
+.. sourcecode:: python
+
+    # -*- encoding:utf-8 -*-
+    from mako.template import Template
+
+    t = Template("drôle de petite voix m’a réveillé.", disable_unicode=True, input_encoding='utf-8')
+    print t.code
+
+The ``disable_unicode`` mode is strictly a Python 2 thing. It is
+not supported at all in Python 3.
+
+The generated module source code will contain elements like
+these:
+
+.. sourcecode:: python
+
+    # -*- encoding:utf-8 -*-
+    #  ...more generated code ...
+
+    def render_body(context,**pageargs):
+        context.caller_stack.push_frame()
+        try:
+            __M_locals = dict(pageargs=pageargs)
+            # SOURCE LINE 1
+            context.write('dr\xc3\xb4le de petite voix m\xe2\x80\x99a r\xc3\xa9veill\xc3\xa9.')
+            return ''
+        finally:
+            context.caller_stack.pop_frame()
+
+Where above that the string literal used within :meth:`.Context.write`
+is a regular byte-string.
+
+When ``disable_unicode=True`` is turned on, the ``default_filters``
+argument which normally defaults to ``["unicode"]`` now defaults
+to ``["str"]`` instead. Setting ``default_filters`` to the empty list
+``[]`` can remove the overhead of the ``str`` call. Also, in this
+mode you **cannot** safely call :meth:`~.Template.render_unicode` -- you'll get
+unicode/decode errors.
+
+The ``h`` filter (HTML escape) uses a less performant pure Python
+escape function in non-unicode mode. This because
+MarkupSafe only supports Python unicode objects for non-ASCII
+strings.
+
+.. versionchanged:: 0.3.4
+   In prior versions, it used ``cgi.escape()``, which has been replaced
+   with a function that also escapes single quotes.
+
+Rules for using ``disable_unicode=True``
+----------------------------------------
+
+* Don't use this mode unless you really, really want to and you
+  absolutely understand what you're doing.
+* Don't use this option just because you don't want to learn to
+  use Unicode properly; we aren't supporting user issues in this
+  mode of operation. We will however offer generous help for the
+  vast majority of users who stick to the Unicode program.
+* Python 3 is unicode by default, and the flag is not available
+  when running on Python 3.
+
diff --git a/lib3/Mako-0.7.3/doc/_sources/usage.txt b/lib3/Mako-0.7.3/doc/_sources/usage.txt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_sources/usage.txt
@@ -0,0 +1,520 @@
+.. _usage_toplevel:
+
+=====
+Usage
+=====
+
+Basic Usage
+===========
+
+This section describes the Python API for Mako templates. If you
+are using Mako within a web framework such as Pylons, the work
+of integrating Mako's API is already done for you, in which case
+you can skip to the next section, :ref:`syntax_toplevel`.
+
+The most basic way to create a template and render it is through
+the :class:`.Template` class:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    mytemplate = Template("hello world!")
+    print mytemplate.render()
+
+Above, the text argument to :class:`.Template` is **compiled** into a
+Python module representation. This module contains a function
+called ``render_body()``, which produces the output of the
+template. When ``mytemplate.render()`` is called, Mako sets up a
+runtime environment for the template and calls the
+``render_body()`` function, capturing the output into a buffer and
+returning its string contents.
+
+
+The code inside the ``render_body()`` function has access to a
+namespace of variables. You can specify these variables by
+sending them as additional keyword arguments to the :meth:`~.Template.render`
+method:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    mytemplate = Template("hello, ${name}!")
+    print mytemplate.render(name="jack")
+
+The :meth:`~.Template.render` method calls upon Mako to create a
+:class:`.Context` object, which stores all the variable names accessible
+to the template and also stores a buffer used to capture output.
+You can create this :class:`.Context` yourself and have the template
+render with it, using the :meth:`~.Template.render_context` method:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.runtime import Context
+    from StringIO import StringIO
+
+    mytemplate = Template("hello, ${name}!")
+    buf = StringIO()
+    ctx = Context(buf, name="jack")
+    mytemplate.render_context(ctx)
+    print buf.getvalue()
+
+Using File-Based Templates
+==========================
+
+A :class:`.Template` can also load its template source code from a file,
+using the ``filename`` keyword argument:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    mytemplate = Template(filename='/docs/mytmpl.txt')
+    print mytemplate.render()
+
+For improved performance, a :class:`.Template` which is loaded from a
+file can also cache the source code to its generated module on
+the filesystem as a regular Python module file (i.e. a ``.py``
+file). To do this, just add the ``module_directory`` argument to
+the template:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules')
+    print mytemplate.render()
+
+When the above code is rendered, a file
+``/tmp/mako_modules/docs/mytmpl.txt.py`` is created containing the
+source code for the module. The next time a :class:`.Template` with the
+same arguments is created, this module file will be
+automatically re-used.
+
+.. _usage_templatelookup:
+
+Using ``TemplateLookup``
+========================
+
+All of the examples thus far have dealt with the usage of a
+single :class:`.Template` object. If the code within those templates
+tries to locate another template resource, it will need some way
+to find them, using simple URI strings. For this need, the
+resolution of other templates from within a template is
+accomplished by the :class:`.TemplateLookup` class. This class is
+constructed given a list of directories in which to search for
+templates, as well as keyword arguments that will be passed to
+the :class:`.Template` objects it creates:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    mylookup = TemplateLookup(directories=['/docs'])
+    mytemplate = Template("""<%include file="header.txt"/> hello world!""", lookup=mylookup)
+
+Above, we created a textual template which includes the file
+``"header.txt"``. In order for it to have somewhere to look for
+``"header.txt"``, we passed a :class:`.TemplateLookup` object to it, which
+will search in the directory ``/docs`` for the file ``"header.txt"``.
+
+Usually, an application will store most or all of its templates
+as text files on the filesystem. So far, all of our examples
+have been a little bit contrived in order to illustrate the
+basic concepts. But a real application would get most or all of
+its templates directly from the :class:`.TemplateLookup`, using the
+aptly named :meth:`~.TemplateLookup.get_template` method, which accepts the URI of the
+desired template:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules')
+
+    def serve_template(templatename, **kwargs):
+        mytemplate = mylookup.get_template(templatename)
+        print mytemplate.render(**kwargs)
+
+In the example above, we create a :class:`.TemplateLookup` which will
+look for templates in the ``/docs`` directory, and will store
+generated module files in the ``/tmp/mako_modules`` directory. The
+lookup locates templates by appending the given URI to each of
+its search directories; so if you gave it a URI of
+``/etc/beans/info.txt``, it would search for the file
+``/docs/etc/beans/info.txt``, else raise a :class:`.TopLevelNotFound`
+exception, which is a custom Mako exception.
+
+When the lookup locates templates, it will also assign a ``uri``
+property to the :class:`.Template` which is the URI passed to the
+:meth:`~.TemplateLookup.get_template()` call. :class:`.Template` uses this URI to calculate the
+name of its module file. So in the above example, a
+``templatename`` argument of ``/etc/beans/info.txt`` will create a
+module file ``/tmp/mako_modules/etc/beans/info.txt.py``.
+
+Setting the Collection Size
+---------------------------
+
+The :class:`.TemplateLookup` also serves the important need of caching a
+fixed set of templates in memory at a given time, so that
+successive URI lookups do not result in full template
+compilations and/or module reloads on each request. By default,
+the :class:`.TemplateLookup` size is unbounded. You can specify a fixed
+size using the ``collection_size`` argument:
+
+.. sourcecode:: python
+
+    mylookup = TemplateLookup(directories=['/docs'],
+                    module_directory='/tmp/mako_modules', collection_size=500)
+
+The above lookup will continue to load templates into memory
+until it reaches a count of around 500. At that point, it will
+clean out a certain percentage of templates using a least
+recently used scheme.
+
+Setting Filesystem Checks
+-------------------------
+
+Another important flag on :class:`.TemplateLookup` is
+``filesystem_checks``. This defaults to ``True``, and says that each
+time a template is returned by the :meth:`~.TemplateLookup.get_template()` method, the
+revision time of the original template file is checked against
+the last time the template was loaded, and if the file is newer
+will reload its contents and recompile the template. On a
+production system, setting ``filesystem_checks`` to ``False`` can
+afford a small to moderate performance increase (depending on
+the type of filesystem used).
+
+.. _usage_unicode:
+
+Using Unicode and Encoding
+==========================
+
+Both :class:`.Template` and :class:`.TemplateLookup` accept ``output_encoding``
+and ``encoding_errors`` parameters which can be used to encode the
+output in any Python supported codec:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
+
+    mytemplate = mylookup.get_template("foo.txt")
+    print mytemplate.render()
+
+When using Python 3, the :meth:`~.Template.render` method will return a ``bytes``
+object, **if** ``output_encoding`` is set. Otherwise it returns a
+``string``.
+
+Additionally, the :meth:`~.Template.render_unicode()` method exists which will
+return the template output as a Python ``unicode`` object, or in
+Python 3 a ``string``:
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode()
+
+The above method disregards the output encoding keyword
+argument; you can encode yourself by saying:
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode().encode('utf-8', 'replace')
+
+Note that Mako's ability to return data in any encoding and/or
+``unicode`` implies that the underlying output stream of the
+template is a Python unicode object. This behavior is described
+fully in :ref:`unicode_toplevel`.
+
+.. _handling_exceptions:
+
+Handling Exceptions
+===================
+
+Template exceptions can occur in two distinct places. One is
+when you **lookup, parse and compile** the template, the other
+is when you **run** the template. Within the running of a
+template, exceptions are thrown normally from whatever Python
+code originated the issue. Mako has its own set of exception
+classes which mostly apply to the lookup and lexer/compiler
+stages of template construction. Mako provides some library
+routines that can be used to help provide Mako-specific
+information about any exception's stack trace, as well as
+formatting the exception within textual or HTML format. In all
+cases, the main value of these handlers is that of converting
+Python filenames, line numbers, and code samples into Mako
+template filenames, line numbers, and code samples. All lines
+within a stack trace which correspond to a Mako template module
+will be converted to be against the originating template file.
+
+To format exception traces, the :func:`.text_error_template` and
+:func:`.html_error_template` functions are provided. They make usage of
+``sys.exc_info()`` to get at the most recently thrown exception.
+Usage of these handlers usually looks like:
+
+.. sourcecode:: python
+
+    from mako import exceptions
+
+    try:
+        template = lookup.get_template(uri)
+        print template.render()
+    except:
+        print exceptions.text_error_template().render()
+
+Or for the HTML render function:
+
+.. sourcecode:: python
+
+    from mako import exceptions
+
+    try:
+        template = lookup.get_template(uri)
+        print template.render()
+    except:
+        print exceptions.html_error_template().render()
+
+The :func:`.html_error_template` template accepts two options:
+specifying ``full=False`` causes only a section of an HTML
+document to be rendered. Specifying ``css=False`` will disable the
+default stylesheet from being rendered.
+
+E.g.:
+
+.. sourcecode:: python
+
+    print exceptions.html_error_template().render(full=False)
+
+The HTML render function is also available built-in to
+:class:`.Template` using the ``format_exceptions`` flag. In this case, any
+exceptions raised within the **render** stage of the template
+will result in the output being substituted with the output of
+:func:`.html_error_template`:
+
+.. sourcecode:: python
+
+    template = Template(filename="/foo/bar", format_exceptions=True)
+    print template.render()
+
+Note that the compile stage of the above template occurs when
+you construct the :class:`.Template` itself, and no output stream is
+defined. Therefore exceptions which occur within the
+lookup/parse/compile stage will not be handled and will
+propagate normally. While the pre-render traceback usually will
+not include any Mako-specific lines anyway, it will mean that
+exceptions which occur previous to rendering and those which
+occur within rendering will be handled differently... so the
+``try``/``except`` patterns described previously are probably of more
+general use.
+
+The underlying object used by the error template functions is
+the :class:`.RichTraceback` object. This object can also be used
+directly to provide custom error views. Here's an example usage
+which describes its general API:
+
+.. sourcecode:: python
+
+    from mako.exceptions import RichTraceback
+
+    try:
+        template = lookup.get_template(uri)
+        print template.render()
+    except:
+        traceback = RichTraceback()
+        for (filename, lineno, function, line) in traceback.traceback:
+            print "File %s, line %s, in %s" % (filename, lineno, function)
+            print line, "\n"
+        print "%s: %s" % (str(traceback.error.__class__.__name__), traceback.error)
+
+Common Framework Integrations
+=============================
+
+The Mako distribution includes a little bit of helper code for
+the purpose of using Mako in some popular web framework
+scenarios. This is a brief description of what's included.
+
+WSGI
+----
+
+A sample WSGI application is included in the distribution in the
+file ``examples/wsgi/run_wsgi.py``. This runner is set up to pull
+files from a `templates` as well as an `htdocs` directory and
+includes a rudimental two-file layout. The WSGI runner acts as a
+fully functional standalone web server, using ``wsgiutils`` to run
+itself, and propagates GET and POST arguments from the request
+into the :class:`.Context`, can serve images, CSS files and other kinds
+of files, and also displays errors using Mako's included
+exception-handling utilities.
+
+Pygments
+--------
+
+A `Pygments <http://pygments.pocoo.org>`_-compatible syntax
+highlighting module is included under :mod:`mako.ext.pygmentplugin`.
+This module is used in the generation of Mako documentation and
+also contains various `setuptools` entry points under the heading
+``pygments.lexers``, including ``mako``, ``html+mako``, ``xml+mako``
+(see the ``setup.py`` file for all the entry points).
+
+Babel
+-----
+
+Mako provides support for extracting `gettext` messages from
+templates via a `Babel`_ extractor
+entry point under ``mako.ext.babelplugin``.
+
+`Gettext` messages are extracted from all Python code sections,
+including those of control lines and expressions embedded
+in tags.
+
+`Translator
+comments <http://babel.edgewall.org/wiki/Documentation/messages.html#comments-tags-and-translator-comments-explanation>`_
+may also be extracted from Mako templates when a comment tag is
+specified to `Babel`_ (such as with
+the ``-c`` option).
+
+For example, a project ``"myproj"`` contains the following Mako
+template at ``myproj/myproj/templates/name.html``:
+
+.. sourcecode:: mako
+
+    <div id="name">
+      Name:
+      ## TRANSLATORS: This is a proper name. See the gettext
+      ## manual, section Names.
+      ${_('Francois Pinard')}
+    </div>
+
+To extract gettext messages from this template the project needs
+a Mako section in its `Babel Extraction Method Mapping
+file <http://babel.edgewall.org/wiki/Documentation/messages.html#extraction-method-mapping-and-configuration>`_
+(typically located at ``myproj/babel.cfg``):
+
+.. sourcecode:: cfg
+
+    # Extraction from Python source files
+
+    [python: myproj/**.py]
+
+    # Extraction from Mako templates
+
+    [mako: myproj/templates/**.html]
+    input_encoding = utf-8
+
+The Mako extractor supports an optional ``input_encoding``
+parameter specifying the encoding of the templates (identical to
+:class:`.Template`/:class:`.TemplateLookup`'s ``input_encoding`` parameter).
+
+Invoking `Babel`_'s extractor at the
+command line in the project's root directory:
+
+.. sourcecode:: sh
+
+    myproj$ pybabel extract -F babel.cfg -c "TRANSLATORS:" .
+
+will output a `gettext` catalog to `stdout` including the following:
+
+.. sourcecode:: pot
+
+    #. TRANSLATORS: This is a proper name. See the gettext
+    #. manual, section Names.
+    #: myproj/templates/name.html:5
+    msgid "Francois Pinard"
+    msgstr ""
+
+This is only a basic example:
+`Babel`_ can be invoked from ``setup.py``
+and its command line options specified in the accompanying
+``setup.cfg`` via `Babel Distutils/Setuptools
+Integration <http://babel.edgewall.org/wiki/Documentation/setup.html>`_.
+
+Comments must immediately precede a `gettext` message to be
+extracted. In the following case the ``TRANSLATORS:`` comment would
+not have been extracted:
+
+.. sourcecode:: mako
+
+    <div id="name">
+      ## TRANSLATORS: This is a proper name. See the gettext
+      ## manual, section Names.
+      Name: ${_('Francois Pinard')}
+    </div>
+
+See the `Babel User
+Guide <http://babel.edgewall.org/wiki/Documentation/index.html>`_
+for more information.
+
+.. _babel: http://babel.edgewall.org/
+
+
+API Reference
+=============
+
+.. autoclass:: mako.template.Template
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.template.DefTemplate
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.lookup.TemplateCollection
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.lookup.TemplateLookup
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.exceptions.RichTraceback
+    :show-inheritance:
+
+    .. py:attribute:: error
+
+       the exception instance.
+
+    .. py:attribute:: message
+
+       the exception error message as unicode.
+
+    .. py:attribute:: source
+
+       source code of the file where the error occurred.
+       If the error occurred within a compiled template,
+       this is the template source.
+
+    .. py:attribute:: lineno
+
+       line number where the error occurred.  If the error
+       occurred within a compiled template, the line number
+       is adjusted to that of the template source.
+
+    .. py:attribute:: records
+
+       a list of 8-tuples containing the original
+       python traceback elements, plus the
+       filename, line number, source line, and full template source
+       for the traceline mapped back to its originating source
+       template, if any for that traceline (else the fields are ``None``).
+
+    .. py:attribute:: reverse_records
+
+       the list of records in reverse
+       traceback -- a list of 4-tuples, in the same format as a regular
+       python traceback, with template-corresponding
+       traceback records replacing the originals.
+
+    .. py:attribute:: reverse_traceback
+
+       the traceback list in reverse.
+
+.. autofunction:: mako.exceptions.html_error_template
+
+.. autofunction:: mako.exceptions.text_error_template
+
diff --git a/lib3/Mako-0.7.3/doc/_static/basic.css b/lib3/Mako-0.7.3/doc/_static/basic.css
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/basic.css
@@ -0,0 +1,540 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+    clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+    width: 100%;
+    font-size: 90%;
+}
+
+div.related h3 {
+    display: none;
+}
+
+div.related ul {
+    margin: 0;
+    padding: 0 0 0 10px;
+    list-style: none;
+}
+
+div.related li {
+    display: inline;
+}
+
+div.related li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+    float: left;
+    width: 230px;
+    margin-left: -100%;
+    font-size: 90%;
+}
+
+div.sphinxsidebar ul {
+    list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+    margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+    width: 170px;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+    width: 30px;
+}
+
+img {
+    border: 0;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+    width: 90%;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    font-style: italic;
+    padding-top: 5px;
+    font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+    width: 100%;
+}
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+div.modindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+a.headerlink {
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+div.body p.caption {
+    text-align: inherit;
+}
+
+div.body td {
+    text-align: left;
+}
+
+.field-list ul {
+    padding-left: 1em;
+}
+
+.first {
+    margin-top: 0 !important;
+}
+
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+    clear: left;
+    float: left;
+    margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+    clear: right;
+    float: right;
+    margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.align-left {
+    text-align: left;
+}
+
+.align-center {
+    text-align: center;
+}
+
+.align-right {
+    text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+    margin: 0 0 0.5em 1em;
+    border: 1px solid #ddb;
+    padding: 7px 7px 0 7px;
+    background-color: #ffe;
+    width: 40%;
+    float: right;
+}
+
+p.sidebar-title {
+    font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+    border: 1px solid #ccc;
+    padding: 7px 7px 0 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    padding: 7px;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+div.admonition dl {
+    margin-bottom: 0;
+}
+
+p.admonition-title {
+    margin: 0px 10px 5px 0px;
+    font-weight: bold;
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+    border: 0;
+    border-collapse: collapse;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 5px;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+table.citation {
+    border-left: solid 1px gray;
+    margin-left: 1px;
+}
+
+table.citation td {
+    border-bottom: none;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+    list-style: decimal;
+}
+
+ol.loweralpha {
+    list-style: lower-alpha;
+}
+
+ol.upperalpha {
+    list-style: upper-alpha;
+}
+
+ol.lowerroman {
+    list-style: lower-roman;
+}
+
+ol.upperroman {
+    list-style: upper-roman;
+}
+
+dl {
+    margin-bottom: 15px;
+}
+
+dd p {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+dt:target, .highlighted {
+    background-color: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+.field-list ul {
+    margin: 0;
+    padding-left: 1em;
+}
+
+.field-list p {
+    margin: 0;
+}
+
+.refcount {
+    color: #060;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+.footnote:target  {
+    background-color: #ffa;
+}
+
+.line-block {
+    display: block;
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+
+.line-block .line-block {
+    margin-top: 0;
+    margin-bottom: 0;
+    margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+    font-family: sans-serif;
+}
+
+.accelerator {
+    text-decoration: underline;
+}
+
+.classifier {
+    font-style: oblique;
+}
+
+abbr, acronym {
+    border-bottom: dotted 1px;
+    cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+    overflow: auto;
+    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
+}
+
+td.linenos pre {
+    padding: 5px 0px;
+    border: 0;
+    background-color: transparent;
+    color: #aaa;
+}
+
+table.highlighttable {
+    margin-left: 0.5em;
+}
+
+table.highlighttable td {
+    padding: 0 0.5em 0 0.5em;
+}
+
+tt.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+tt.descclassname {
+    background-color: transparent;
+}
+
+tt.xref, a tt {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+    background-color: transparent;
+}
+
+.viewcode-link {
+    float: right;
+}
+
+.viewcode-back {
+    float: right;
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    margin: -1px -10px;
+    padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+    vertical-align: middle;
+}
+
+div.body div.math p {
+    text-align: center;
+}
+
+span.eqno {
+    float: right;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+ at media print {
+    div.document,
+    div.documentwrapper,
+    div.bodywrapper {
+        margin: 0 !important;
+        width: 100%;
+    }
+
+    div.sphinxsidebar,
+    div.related,
+    div.footer,
+    #top-link {
+        display: none;
+    }
+}
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/doc/_static/comment-bright.png b/lib3/Mako-0.7.3/doc/_static/comment-bright.png
new file mode 100644
index 0000000000000000000000000000000000000000..551517b8c83b76f734ff791f847829a760ad1903
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/comment-close.png b/lib3/Mako-0.7.3/doc/_static/comment-close.png
new file mode 100644
index 0000000000000000000000000000000000000000..09b54be46da3f0d4a5061da289dc91d8a2cdbc9c
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/comment.png b/lib3/Mako-0.7.3/doc/_static/comment.png
new file mode 100644
index 0000000000000000000000000000000000000000..92feb52b8824c6b0f59b658b1196c61de9162a95
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/default.css b/lib3/Mako-0.7.3/doc/_static/default.css
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/default.css
@@ -0,0 +1,256 @@
+/*
+ * default.css_t
+ * ~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- default theme.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+ at import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: sans-serif;
+    font-size: 100%;
+    background-color: #11303d;
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+div.document {
+    background-color: #1c4e63;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+}
+
+div.body {
+    background-color: #ffffff;
+    color: #000000;
+    padding: 0 20px 30px 20px;
+}
+
+div.footer {
+    color: #ffffff;
+    width: 100%;
+    padding: 9px 0 9px 0;
+    text-align: center;
+    font-size: 75%;
+}
+
+div.footer a {
+    color: #ffffff;
+    text-decoration: underline;
+}
+
+div.related {
+    background-color: #133f52;
+    line-height: 30px;
+    color: #ffffff;
+}
+
+div.related a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar {
+}
+
+div.sphinxsidebar h3 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+}
+
+div.sphinxsidebar h3 a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar h4 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.3em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+}
+
+div.sphinxsidebar p {
+    color: #ffffff;
+}
+
+div.sphinxsidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+    margin: 10px;
+    padding: 0;
+    color: #ffffff;
+}
+
+div.sphinxsidebar a {
+    color: #98dbcc;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+
+
+/* -- hyperlink styles ------------------------------------------------------ */
+
+a {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:visited {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+
+
+/* -- body styles ----------------------------------------------------------- */
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Trebuchet MS', sans-serif;
+    background-color: #f2f2f2;
+    font-weight: normal;
+    color: #20435c;
+    border-bottom: 1px solid #ccc;
+    margin: 20px -20px 10px -20px;
+    padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 140%; }
+div.body h4 { font-size: 120%; }
+div.body h5 { font-size: 110%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+    color: #c60f0f;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+}
+
+a.headerlink:hover {
+    background-color: #c60f0f;
+    color: white;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.admonition p.admonition-title + p {
+    display: inline;
+}
+
+div.admonition p {
+    margin-bottom: 5px;
+}
+
+div.admonition pre {
+    margin-bottom: 5px;
+}
+
+div.admonition ul, div.admonition ol {
+    margin-bottom: 5px;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.topic {
+    background-color: #eee;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+p.admonition-title {
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+pre {
+    padding: 5px;
+    background-color: #eeffcc;
+    color: #333333;
+    line-height: 120%;
+    border: 1px solid #ac9;
+    border-left: none;
+    border-right: none;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0 1px 0 1px;
+    font-size: 0.95em;
+}
+
+th {
+    background-color: #ede;
+}
+
+.warning tt {
+    background: #efc2c2;
+}
+
+.note tt {
+    background: #d6d6d6;
+}
+
+.viewcode-back {
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    background-color: #f4debf;
+    border-top: 1px solid #ac9;
+    border-bottom: 1px solid #ac9;
+}
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/doc/_static/docs.css b/lib3/Mako-0.7.3/doc/_static/docs.css
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/docs.css
@@ -0,0 +1,438 @@
+/* global */
+
+body {
+  background-color: #FDFBFC;
+  margin:38px;
+  color:#333333;
+}
+
+a {
+    font-weight:normal; 
+    text-decoration:none;
+}
+
+form {
+    display:inline;
+}
+
+/* hyperlinks */
+
+a:link, a:visited, a:active {
+    color:#0000FF;
+}
+a:hover {
+    color:#700000;
+    text-decoration:underline;
+}
+
+/* paragraph links after sections.
+   These aren't visible until hovering
+   over the <h> tag, then have a 
+   "reverse video" effect over the actual
+   link
+ */
+
+a.headerlink {
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+a.headerlink:hover {
+    background-color: #990000;
+    color: white;
+}
+
+
+/* Container setup */
+
+#docs-container {
+  max-width:1000px;
+}
+
+
+/* header/footer elements */
+
+#docs-header h1 {
+    font-size:20px;
+    color: #222222;
+    margin: 0;
+    padding: 0;
+}
+
+#docs-header {
+  font-family:Tahoma, Geneva,sans-serif;
+
+  font-size:.9em;
+
+}
+
+#docs-top-navigation,
+#docs-bottom-navigation {
+  font-family: Tahoma, Geneva, sans-serif;
+  background-color: #EEE;
+  border: solid 1px #CCC;
+  padding:10px;
+  font-size:.9em;
+}
+
+#docs-top-navigation {
+  margin:10px 0px 10px 0px;
+  line-height:1.2em;
+}
+
+.docs-navigation-links {
+  font-family:Tahoma, Geneva,sans-serif;
+}
+
+#docs-bottom-navigation {
+    float:right;
+    margin: 1em 0 1em 5px;
+}
+
+#docs-copyright {
+    font-size:.85em;
+    padding:5px 0px;
+}
+
+#docs-header h1,
+#docs-top-navigation h1,
+#docs-top-navigation h2 {
+  font-family:Tahoma,Geneva,sans-serif;
+  font-weight:normal;
+}
+
+#docs-top-navigation h2 {
+    margin:16px 4px 7px 5px;
+    font-size:2em;
+}
+
+#docs-search {
+    float:right;
+}
+
+#docs-top-page-control {
+  float:right;
+  width:350px;
+}
+
+#docs-top-page-control ul {
+  padding:0;
+  margin:0;
+}
+
+#docs-top-page-control li {
+    list-style-type:none;
+    padding:1px 8px;
+}
+
+
+#docs-container .version-num {
+    font-weight: bold;
+}
+
+
+/* content container, sidebar */
+
+#docs-body-container {
+  background-color:#EFEFEF;
+  border: solid 1px #CCC;
+
+}
+
+#docs-body,
+#docs-sidebar
+ {
+  /*font-family: helvetica, arial, sans-serif;
+  font-size:.9em;*/
+
+  font-family: Tahoma, Geneva, sans-serif;
+  /*font-size:.85em;*/
+  line-height:1.5em;
+
+}
+
+#docs-sidebar > ul {
+  font-size:.9em;
+}
+
+#docs-sidebar {
+  float:left;
+  width:212px;
+  padding: 10px 0 0 15px;
+  /*font-size:.85em;*/
+}
+
+#docs-sidebar h3, #docs-sidebar h4 {
+    background-color: #DDDDDD;
+    color: #222222;
+    font-family: Tahoma, Geneva,sans-serif;
+    font-size: 1.1em;
+    font-weight: normal;
+    margin: 10px 0 0 -15px;
+    padding: 5px 10px 5px 10px;
+    text-shadow: 1px 1px 0 white;
+    width:210px;
+}
+
+#docs-sidebar h3 a, #docs-sidebar h4 a {
+  color: #222222;
+}
+#docs-sidebar ul {
+  margin: 10px 10px 10px 0px;
+  padding: 0;
+  list-style: none outside none;
+}
+
+
+#docs-sidebar ul ul {
+    margin-bottom: 0;
+    margin-top: 0;
+    list-style: square outside none;
+    margin-left: 20px;
+}
+
+#docs-body {
+  background-color:#FFFFFF;
+  padding:1px 10px 10px 10px;
+}
+
+#docs-body.withsidebar {
+  margin: 0 0 0 230px;
+  border-left:3px solid #DFDFDF;
+}
+
+#docs-body h1,
+#docs-body h2,
+#docs-body h3,
+#docs-body h4 {
+  font-family:Tahoma, Geneva, sans-serif;
+}
+
+#docs-body h1 {
+  /* hide the <h1> for each content section. */
+  display:none;
+  font-size:1.8em;
+}
+
+#docs-body h2 {
+  font-size:1.6em;
+}
+
+#docs-body h3 {
+  font-size:1.4em;
+}
+
+/* SQL popup, code styles */
+
+.highlight {
+  background:none;
+}
+
+#docs-container pre {
+  font-size:1.2em;
+}
+
+#docs-container .pre {
+  font-size:1.1em;
+}
+
+#docs-container pre {
+  background-color: #f0f0f0;  
+  border: solid 1px #ccc;
+  box-shadow: 2px 2px 3px #DFDFDF;
+  padding:10px;
+  margin: 5px 0px 5px 0px;
+  overflow:auto;
+  line-height:1.3em;
+}
+
+.popup_sql, .show_sql
+{
+    background-color: #FBFBEE;
+    padding:5px 10px;
+    margin:10px -5px;
+    border:1px dashed;
+}
+
+/* the [SQL] links used to display SQL */
+#docs-container .sql_link
+{
+  font-weight:normal;
+  font-family: arial, sans-serif;
+  font-size:.9em;
+  text-transform: uppercase;
+  color:#990000;
+  border:1px solid;
+  padding:1px 2px 1px 2px;
+  margin:0px 10px 0px 15px;
+  float:right;
+  line-height:1.2em;
+}
+
+#docs-container a.sql_link, 
+#docs-container .sql_link
+{
+    text-decoration: none;
+    padding:1px 2px;
+}
+
+#docs-container a.sql_link:hover {
+    text-decoration: none;
+    color:#fff;
+    border:1px solid #900;
+    background-color: #900;
+}
+
+/* docutils-specific elements */
+
+th.field-name {
+    text-align:right;
+}
+
+div.note, div.warning, p.deprecated, div.topic  {
+    background-color:#EEFFEF;
+}
+
+
+div.admonition, div.topic, p.deprecated, p.versionadded, p.versionchanged {
+    border:1px solid #CCCCCC;
+    padding:5px 10px;
+    font-size:.9em;
+    box-shadow: 2px 2px 3px #DFDFDF;
+}
+
+div.warning .admonition-title {
+    color:#FF0000;
+}
+
+div.admonition .admonition-title, div.topic .topic-title {
+    font-weight:bold;
+}
+
+.viewcode-back, .viewcode-link {
+    float:right;
+}
+
+dl.function > dt,
+dl.attribute > dt,
+dl.classmethod > dt,
+dl.method > dt,
+dl.class > dt,
+dl.exception > dt
+{
+    background-color:#F0F0F0;
+    margin:25px -10px 10px 10px;
+    padding: 0px 10px;
+}
+
+p.versionadded span.versionmodified,
+p.versionchanged span.versionmodified,
+p.deprecated span.versionmodified {
+    background-color: #F0F0F0;
+    font-style: italic;
+}
+
+dt:target, span.highlight {
+    background-color:#FBE54E;
+}
+
+a.headerlink {
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+a.headerlink:hover {
+    background-color: #00f;
+    color: white;
+}
+
+.clearboth {
+    clear:both;
+}
+
+tt.descname {
+    background-color:transparent;
+    font-size:1.2em;
+    font-weight:bold;
+}
+
+tt.descclassname {
+    background-color:transparent;
+}
+
+tt {
+    background-color:#ECF0F3;
+    padding:0 1px;
+}
+
+/* syntax highlighting overrides */
+.k, .kn {color:#0908CE;}
+.o {color:#BF0005;}
+.go {color:#804049;}
+
+
+/* special "index page" sections 
+   with specific formatting
+*/
+
+div#sqlalchemy-documentation {
+  font-size:.95em;
+}
+div#sqlalchemy-documentation em {
+  font-style:normal;
+}
+div#sqlalchemy-documentation .rubric{
+  font-size:14px;
+  background-color:#EEFFEF;
+  padding:5px;
+  border:1px solid #BFBFBF;
+}
+div#sqlalchemy-documentation a, div#sqlalchemy-documentation li {
+  padding:5px 0px;
+}
+
+div#getting-started {
+  border-bottom:1px solid;
+}
+
+div#sqlalchemy-documentation div#sqlalchemy-orm {
+  float:left;
+  width:48%;
+}
+
+div#sqlalchemy-documentation div#sqlalchemy-core {
+  float:left;
+  width:48%;
+  margin:0;
+  padding-left:10px;
+  border-left:1px solid;
+}
+
+div#dialect-documentation {
+  border-top:1px solid;
+  /*clear:left;*/
+}
diff --git a/lib3/Mako-0.7.3/doc/_static/doctools.js b/lib3/Mako-0.7.3/doc/_static/doctools.js
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/doctools.js
@@ -0,0 +1,247 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for all documentation.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+if (!window.console || !console.firebug) {
+  var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
+    "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
+    "profile", "profileEnd"];
+  window.console = {};
+  for (var i = 0; i < names.length; ++i)
+    window.console[names[i]] = function() {};
+}
+ */
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+  return decodeURIComponent(x).replace(/\+/g, ' ');
+}
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+  if (typeof s == 'undefined')
+    s = document.location.search;
+  var parts = s.substr(s.indexOf('?') + 1).split('&');
+  var result = {};
+  for (var i = 0; i < parts.length; i++) {
+    var tmp = parts[i].split('=', 2);
+    var key = jQuery.urldecode(tmp[0]);
+    var value = jQuery.urldecode(tmp[1]);
+    if (key in result)
+      result[key].push(value);
+    else
+      result[key] = [value];
+  }
+  return result;
+};
+
+/**
+ * small function to check if an array contains
+ * a given item.
+ */
+jQuery.contains = function(arr, item) {
+  for (var i = 0; i < arr.length; i++) {
+    if (arr[i] == item)
+      return true;
+  }
+  return false;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+  function highlight(node) {
+    if (node.nodeType == 3) {
+      var val = node.nodeValue;
+      var pos = val.toLowerCase().indexOf(text);
+      if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
+        var span = document.createElement("span");
+        span.className = className;
+        span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+        node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+          document.createTextNode(val.substr(pos + text.length)),
+          node.nextSibling));
+        node.nodeValue = val.substr(0, pos);
+      }
+    }
+    else if (!jQuery(node).is("button, select, textarea")) {
+      jQuery.each(node.childNodes, function() {
+        highlight(this);
+      });
+    }
+  }
+  return this.each(function() {
+    highlight(this);
+  });
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+  init : function() {
+    this.fixFirefoxAnchorBug();
+    this.highlightSearchWords();
+    this.initIndexTable();
+  },
+
+  /**
+   * i18n support
+   */
+  TRANSLATIONS : {},
+  PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
+  LOCALE : 'unknown',
+
+  // gettext and ngettext don't access this so that the functions
+  // can safely bound to a different name (_ = Documentation.gettext)
+  gettext : function(string) {
+    var translated = Documentation.TRANSLATIONS[string];
+    if (typeof translated == 'undefined')
+      return string;
+    return (typeof translated == 'string') ? translated : translated[0];
+  },
+
+  ngettext : function(singular, plural, n) {
+    var translated = Documentation.TRANSLATIONS[singular];
+    if (typeof translated == 'undefined')
+      return (n == 1) ? singular : plural;
+    return translated[Documentation.PLURALEXPR(n)];
+  },
+
+  addTranslations : function(catalog) {
+    for (var key in catalog.messages)
+      this.TRANSLATIONS[key] = catalog.messages[key];
+    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+    this.LOCALE = catalog.locale;
+  },
+
+  /**
+   * add context elements like header anchor links
+   */
+  addContextElements : function() {
+    $('div[id] > :header:first').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this headline')).
+      appendTo(this);
+    });
+    $('dt[id]').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this definition')).
+      appendTo(this);
+    });
+  },
+
+  /**
+   * workaround a firefox stupidity
+   */
+  fixFirefoxAnchorBug : function() {
+    if (document.location.hash && $.browser.mozilla)
+      window.setTimeout(function() {
+        document.location.href += '';
+      }, 10);
+  },
+
+  /**
+   * highlight the search words provided in the url in the text
+   */
+  highlightSearchWords : function() {
+    var params = $.getQueryParameters();
+    var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+    if (terms.length) {
+      var body = $('div.body');
+      window.setTimeout(function() {
+        $.each(terms, function() {
+          body.highlightText(this.toLowerCase(), 'highlighted');
+        });
+      }, 10);
+      $('<p class="highlight-link"><a href="javascript:Documentation.' +
+        'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
+          .appendTo($('#searchbox'));
+    }
+  },
+
+  /**
+   * init the domain index toggle buttons
+   */
+  initIndexTable : function() {
+    var togglers = $('img.toggler').click(function() {
+      var src = $(this).attr('src');
+      var idnum = $(this).attr('id').substr(7);
+      $('tr.cg-' + idnum).toggle();
+      if (src.substr(-9) == 'minus.png')
+        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+      else
+        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+    }).css('display', '');
+    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
+        togglers.click();
+    }
+  },
+
+  /**
+   * helper function to hide the search marks again
+   */
+  hideSearchWords : function() {
+    $('#searchbox .highlight-link').fadeOut(300);
+    $('span.highlighted').removeClass('highlighted');
+  },
+
+  /**
+   * make the url absolute
+   */
+  makeURL : function(relativeURL) {
+    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+  },
+
+  /**
+   * get the current relative url
+   */
+  getCurrentURL : function() {
+    var path = document.location.pathname;
+    var parts = path.split(/\//);
+    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+      if (this == '..')
+        parts.pop();
+    });
+    var url = parts.join('/');
+    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+  }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+  Documentation.init();
+});
diff --git a/lib3/Mako-0.7.3/doc/_static/down-pressed.png b/lib3/Mako-0.7.3/doc/_static/down-pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f7ad782782e4f8e39b0c6e15c7344700cdd2527
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/down.png b/lib3/Mako-0.7.3/doc/_static/down.png
new file mode 100644
index 0000000000000000000000000000000000000000..3003a88770de3977d47a2ba69893436a2860f9e7
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/file.png b/lib3/Mako-0.7.3/doc/_static/file.png
new file mode 100644
index 0000000000000000000000000000000000000000..d18082e397e7e54f20721af768c4c2983258f1b4
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/jquery.js b/lib3/Mako-0.7.3/doc/_static/jquery.js
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/jquery.js
@@ -0,0 +1,154 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
diff --git a/lib3/Mako-0.7.3/doc/_static/makoLogo.png b/lib3/Mako-0.7.3/doc/_static/makoLogo.png
new file mode 100644
index 0000000000000000000000000000000000000000..c43c087eb48ebfc2223b76cf3df2fa7868c2a72b
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/minus.png b/lib3/Mako-0.7.3/doc/_static/minus.png
new file mode 100644
index 0000000000000000000000000000000000000000..da1c5620d10c047525a467a425abe9ff5269cfc2
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/plus.png b/lib3/Mako-0.7.3/doc/_static/plus.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3cb37425ea68b39ffa7b2e5fb69161275a87541
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/pygments.css b/lib3/Mako-0.7.3/doc/_static/pygments.css
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/pygments.css
@@ -0,0 +1,62 @@
+.highlight .hll { background-color: #ffffcc }
+.highlight  { background: #eeffcc; }
+.highlight .c { color: #408090; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #007020; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #007020 } /* Comment.Preproc */
+.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #303030 } /* Generic.Output */
+.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0040D0 } /* Generic.Traceback */
+.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #007020 } /* Keyword.Pseudo */
+.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #902000 } /* Keyword.Type */
+.highlight .m { color: #208050 } /* Literal.Number */
+.highlight .s { color: #4070a0 } /* Literal.String */
+.highlight .na { color: #4070a0 } /* Name.Attribute */
+.highlight .nb { color: #007020 } /* Name.Builtin */
+.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.highlight .no { color: #60add5 } /* Name.Constant */
+.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #007020 } /* Name.Exception */
+.highlight .nf { color: #06287e } /* Name.Function */
+.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
+.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #bb60d5 } /* Name.Variable */
+.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #208050 } /* Literal.Number.Float */
+.highlight .mh { color: #208050 } /* Literal.Number.Hex */
+.highlight .mi { color: #208050 } /* Literal.Number.Integer */
+.highlight .mo { color: #208050 } /* Literal.Number.Oct */
+.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
+.highlight .sc { color: #4070a0 } /* Literal.String.Char */
+.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
+.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
+.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.highlight .sx { color: #c65d09 } /* Literal.String.Other */
+.highlight .sr { color: #235388 } /* Literal.String.Regex */
+.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
+.highlight .ss { color: #517918 } /* Literal.String.Symbol */
+.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
+.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
+.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
+.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/doc/_static/searchtools.js b/lib3/Mako-0.7.3/doc/_static/searchtools.js
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/searchtools.js
@@ -0,0 +1,560 @@
+/*
+ * searchtools.js_t
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilties for the full-text search.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words, hlwords is the list of normal, unstemmed
+ * words. the first one is used to find the occurance, the
+ * latter for highlighting it.
+ */
+
+jQuery.makeSearchSummary = function(text, keywords, hlwords) {
+  var textLower = text.toLowerCase();
+  var start = 0;
+  $.each(keywords, function() {
+    var i = textLower.indexOf(this.toLowerCase());
+    if (i > -1)
+      start = i;
+  });
+  start = Math.max(start - 120, 0);
+  var excerpt = ((start > 0) ? '...' : '') +
+  $.trim(text.substr(start, 240)) +
+  ((start + 240 - text.length) ? '...' : '');
+  var rv = $('<div class="context"></div>').text(excerpt);
+  $.each(hlwords, function() {
+    rv = rv.highlightText(this, 'highlighted');
+  });
+  return rv;
+}
+
+
+/**
+ * Porter Stemmer
+ */
+var Stemmer = function() {
+
+  var step2list = {
+    ational: 'ate',
+    tional: 'tion',
+    enci: 'ence',
+    anci: 'ance',
+    izer: 'ize',
+    bli: 'ble',
+    alli: 'al',
+    entli: 'ent',
+    eli: 'e',
+    ousli: 'ous',
+    ization: 'ize',
+    ation: 'ate',
+    ator: 'ate',
+    alism: 'al',
+    iveness: 'ive',
+    fulness: 'ful',
+    ousness: 'ous',
+    aliti: 'al',
+    iviti: 'ive',
+    biliti: 'ble',
+    logi: 'log'
+  };
+
+  var step3list = {
+    icate: 'ic',
+    ative: '',
+    alize: 'al',
+    iciti: 'ic',
+    ical: 'ic',
+    ful: '',
+    ness: ''
+  };
+
+  var c = "[^aeiou]";          // consonant
+  var v = "[aeiouy]";          // vowel
+  var C = c + "[^aeiouy]*";    // consonant sequence
+  var V = v + "[aeiou]*";      // vowel sequence
+
+  var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
+  var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
+  var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
+  var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
+
+  this.stemWord = function (w) {
+    var stem;
+    var suffix;
+    var firstch;
+    var origword = w;
+
+    if (w.length < 3)
+      return w;
+
+    var re;
+    var re2;
+    var re3;
+    var re4;
+
+    firstch = w.substr(0,1);
+    if (firstch == "y")
+      w = firstch.toUpperCase() + w.substr(1);
+
+    // Step 1a
+    re = /^(.+?)(ss|i)es$/;
+    re2 = /^(.+?)([^s])s$/;
+
+    if (re.test(w))
+      w = w.replace(re,"$1$2");
+    else if (re2.test(w))
+      w = w.replace(re2,"$1$2");
+
+    // Step 1b
+    re = /^(.+?)eed$/;
+    re2 = /^(.+?)(ed|ing)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      re = new RegExp(mgr0);
+      if (re.test(fp[1])) {
+        re = /.$/;
+        w = w.replace(re,"");
+      }
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1];
+      re2 = new RegExp(s_v);
+      if (re2.test(stem)) {
+        w = stem;
+        re2 = /(at|bl|iz)$/;
+        re3 = new RegExp("([^aeiouylsz])\\1$");
+        re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+        if (re2.test(w))
+          w = w + "e";
+        else if (re3.test(w)) {
+          re = /.$/;
+          w = w.replace(re,"");
+        }
+        else if (re4.test(w))
+          w = w + "e";
+      }
+    }
+
+    // Step 1c
+    re = /^(.+?)y$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(s_v);
+      if (re.test(stem))
+        w = stem + "i";
+    }
+
+    // Step 2
+    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step2list[suffix];
+    }
+
+    // Step 3
+    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step3list[suffix];
+    }
+
+    // Step 4
+    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+    re2 = /^(.+?)(s|t)(ion)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      if (re.test(stem))
+        w = stem;
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1] + fp[2];
+      re2 = new RegExp(mgr1);
+      if (re2.test(stem))
+        w = stem;
+    }
+
+    // Step 5
+    re = /^(.+?)e$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      re2 = new RegExp(meq1);
+      re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+        w = stem;
+    }
+    re = /ll$/;
+    re2 = new RegExp(mgr1);
+    if (re.test(w) && re2.test(w)) {
+      re = /.$/;
+      w = w.replace(re,"");
+    }
+
+    // and turn initial Y back to y
+    if (firstch == "y")
+      w = firstch.toLowerCase() + w.substr(1);
+    return w;
+  }
+}
+
+
+/**
+ * Search Module
+ */
+var Search = {
+
+  _index : null,
+  _queued_query : null,
+  _pulse_status : -1,
+
+  init : function() {
+      var params = $.getQueryParameters();
+      if (params.q) {
+          var query = params.q[0];
+          $('input[name="q"]')[0].value = query;
+          this.performSearch(query);
+      }
+  },
+
+  loadIndex : function(url) {
+    $.ajax({type: "GET", url: url, data: null, success: null,
+            dataType: "script", cache: true});
+  },
+
+  setIndex : function(index) {
+    var q;
+    this._index = index;
+    if ((q = this._queued_query) !== null) {
+      this._queued_query = null;
+      Search.query(q);
+    }
+  },
+
+  hasIndex : function() {
+      return this._index !== null;
+  },
+
+  deferQuery : function(query) {
+      this._queued_query = query;
+  },
+
+  stopPulse : function() {
+      this._pulse_status = 0;
+  },
+
+  startPulse : function() {
+    if (this._pulse_status >= 0)
+        return;
+    function pulse() {
+      Search._pulse_status = (Search._pulse_status + 1) % 4;
+      var dotString = '';
+      for (var i = 0; i < Search._pulse_status; i++)
+        dotString += '.';
+      Search.dots.text(dotString);
+      if (Search._pulse_status > -1)
+        window.setTimeout(pulse, 500);
+    };
+    pulse();
+  },
+
+  /**
+   * perform a search for something
+   */
+  performSearch : function(query) {
+    // create the required interface elements
+    this.out = $('#search-results');
+    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
+    this.dots = $('<span></span>').appendTo(this.title);
+    this.status = $('<p style="display: none"></p>').appendTo(this.out);
+    this.output = $('<ul class="search"/>').appendTo(this.out);
+
+    $('#search-progress').text(_('Preparing search...'));
+    this.startPulse();
+
+    // index already loaded, the browser was quick!
+    if (this.hasIndex())
+      this.query(query);
+    else
+      this.deferQuery(query);
+  },
+
+  query : function(query) {
+    var stopwords = ["and","then","into","it","as","are","in","if","for","no","there","their","was","is","be","to","that","but","they","not","such","with","by","a","on","these","of","will","this","near","the","or","at"];
+
+    // Stem the searchterms and add them to the correct list
+    var stemmer = new Stemmer();
+    var searchterms = [];
+    var excluded = [];
+    var hlterms = [];
+    var tmp = query.split(/\s+/);
+    var objectterms = [];
+    for (var i = 0; i < tmp.length; i++) {
+      if (tmp[i] != "") {
+          objectterms.push(tmp[i].toLowerCase());
+      }
+
+      if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
+          tmp[i] == "") {
+        // skip this "word"
+        continue;
+      }
+      // stem the word
+      var word = stemmer.stemWord(tmp[i]).toLowerCase();
+      // select the correct list
+      if (word[0] == '-') {
+        var toAppend = excluded;
+        word = word.substr(1);
+      }
+      else {
+        var toAppend = searchterms;
+        hlterms.push(tmp[i].toLowerCase());
+      }
+      // only add if not already in the list
+      if (!$.contains(toAppend, word))
+        toAppend.push(word);
+    };
+    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+    // console.debug('SEARCH: searching for:');
+    // console.info('required: ', searchterms);
+    // console.info('excluded: ', excluded);
+
+    // prepare search
+    var filenames = this._index.filenames;
+    var titles = this._index.titles;
+    var terms = this._index.terms;
+    var fileMap = {};
+    var files = null;
+    // different result priorities
+    var importantResults = [];
+    var objectResults = [];
+    var regularResults = [];
+    var unimportantResults = [];
+    $('#search-progress').empty();
+
+    // lookup as object
+    for (var i = 0; i < objectterms.length; i++) {
+      var others = [].concat(objectterms.slice(0,i),
+                             objectterms.slice(i+1, objectterms.length))
+      var results = this.performObjectSearch(objectterms[i], others);
+      // Assume first word is most likely to be the object,
+      // other words more likely to be in description.
+      // Therefore put matches for earlier words first.
+      // (Results are eventually used in reverse order).
+      objectResults = results[0].concat(objectResults);
+      importantResults = results[1].concat(importantResults);
+      unimportantResults = results[2].concat(unimportantResults);
+    }
+
+    // perform the search on the required terms
+    for (var i = 0; i < searchterms.length; i++) {
+      var word = searchterms[i];
+      // no match but word was a required one
+      if ((files = terms[word]) == null)
+        break;
+      if (files.length == undefined) {
+        files = [files];
+      }
+      // create the mapping
+      for (var j = 0; j < files.length; j++) {
+        var file = files[j];
+        if (file in fileMap)
+          fileMap[file].push(word);
+        else
+          fileMap[file] = [word];
+      }
+    }
+
+    // now check if the files don't contain excluded terms
+    for (var file in fileMap) {
+      var valid = true;
+
+      // check if all requirements are matched
+      if (fileMap[file].length != searchterms.length)
+        continue;
+
+      // ensure that none of the excluded terms is in the
+      // search result.
+      for (var i = 0; i < excluded.length; i++) {
+        if (terms[excluded[i]] == file ||
+            $.contains(terms[excluded[i]] || [], file)) {
+          valid = false;
+          break;
+        }
+      }
+
+      // if we have still a valid result we can add it
+      // to the result list
+      if (valid)
+        regularResults.push([filenames[file], titles[file], '', null]);
+    }
+
+    // delete unused variables in order to not waste
+    // memory until list is retrieved completely
+    delete filenames, titles, terms;
+
+    // now sort the regular results descending by title
+    regularResults.sort(function(a, b) {
+      var left = a[1].toLowerCase();
+      var right = b[1].toLowerCase();
+      return (left > right) ? -1 : ((left < right) ? 1 : 0);
+    });
+
+    // combine all results
+    var results = unimportantResults.concat(regularResults)
+      .concat(objectResults).concat(importantResults);
+
+    // print the results
+    var resultCount = results.length;
+    function displayNextItem() {
+      // results left, load the summary and display it
+      if (results.length) {
+        var item = results.pop();
+        var listItem = $('<li style="display:none"></li>');
+        if (DOCUMENTATION_OPTIONS.FILE_SUFFIX == '') {
+          // dirhtml builder
+          var dirname = item[0] + '/';
+          if (dirname.match(/\/index\/$/)) {
+            dirname = dirname.substring(0, dirname.length-6);
+          } else if (dirname == 'index/') {
+            dirname = '';
+          }
+          listItem.append($('<a/>').attr('href',
+            DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
+            highlightstring + item[2]).html(item[1]));
+        } else {
+          // normal html builders
+          listItem.append($('<a/>').attr('href',
+            item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+            highlightstring + item[2]).html(item[1]));
+        }
+        if (item[3]) {
+          listItem.append($('<span> (' + item[3] + ')</span>'));
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+          $.get(DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' +
+                item[0] + '.txt', function(data) {
+            if (data != '') {
+              listItem.append($.makeSearchSummary(data, searchterms, hlterms));
+              Search.output.append(listItem);
+            }
+            listItem.slideDown(5, function() {
+              displayNextItem();
+            });
+          }, "text");
+        } else {
+          // no source available, just display title
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        }
+      }
+      // search finished, update title and status message
+      else {
+        Search.stopPulse();
+        Search.title.text(_('Search Results'));
+        if (!resultCount)
+          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+        else
+            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+        Search.status.fadeIn(500);
+      }
+    }
+    displayNextItem();
+  },
+
+  performObjectSearch : function(object, otherterms) {
+    var filenames = this._index.filenames;
+    var objects = this._index.objects;
+    var objnames = this._index.objnames;
+    var titles = this._index.titles;
+
+    var importantResults = [];
+    var objectResults = [];
+    var unimportantResults = [];
+
+    for (var prefix in objects) {
+      for (var name in objects[prefix]) {
+        var fullname = (prefix ? prefix + '.' : '') + name;
+        if (fullname.toLowerCase().indexOf(object) > -1) {
+          var match = objects[prefix][name];
+          var objname = objnames[match[1]][2];
+          var title = titles[match[0]];
+          // If more than one term searched for, we require other words to be
+          // found in the name/title/description
+          if (otherterms.length > 0) {
+            var haystack = (prefix + ' ' + name + ' ' +
+                            objname + ' ' + title).toLowerCase();
+            var allfound = true;
+            for (var i = 0; i < otherterms.length; i++) {
+              if (haystack.indexOf(otherterms[i]) == -1) {
+                allfound = false;
+                break;
+              }
+            }
+            if (!allfound) {
+              continue;
+            }
+          }
+          var descr = objname + _(', in ') + title;
+          anchor = match[3];
+          if (anchor == '')
+            anchor = fullname;
+          else if (anchor == '-')
+            anchor = objnames[match[1]][1] + '-' + fullname;
+          result = [filenames[match[0]], fullname, '#'+anchor, descr];
+          switch (match[2]) {
+          case 1: objectResults.push(result); break;
+          case 0: importantResults.push(result); break;
+          case 2: unimportantResults.push(result); break;
+          }
+        }
+      }
+    }
+
+    // sort results descending
+    objectResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    importantResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    unimportantResults.sort(function(a, b) {
+      return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+    });
+
+    return [importantResults, objectResults, unimportantResults]
+  }
+}
+
+$(document).ready(function() {
+  Search.init();
+});
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/doc/_static/sidebar.js b/lib3/Mako-0.7.3/doc/_static/sidebar.js
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/sidebar.js
@@ -0,0 +1,151 @@
+/*
+ * sidebar.js
+ * ~~~~~~~~~~
+ *
+ * This script makes the Sphinx sidebar collapsible.
+ *
+ * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds
+ * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
+ * used to collapse and expand the sidebar.
+ *
+ * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
+ * and the width of the sidebar and the margin-left of the document
+ * are decreased. When the sidebar is expanded the opposite happens.
+ * This script saves a per-browser/per-session cookie used to
+ * remember the position of the sidebar among the pages.
+ * Once the browser is closed the cookie is deleted and the position
+ * reset to the default (expanded).
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+$(function() {
+  // global elements used by the functions.
+  // the 'sidebarbutton' element is defined as global after its
+  // creation, in the add_sidebar_button function
+  var bodywrapper = $('.bodywrapper');
+  var sidebar = $('.sphinxsidebar');
+  var sidebarwrapper = $('.sphinxsidebarwrapper');
+
+  // for some reason, the document has no sidebar; do not run into errors
+  if (!sidebar.length) return;
+
+  // original margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar expanded
+  var bw_margin_expanded = bodywrapper.css('margin-left');
+  var ssb_width_expanded = sidebar.width();
+
+  // margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar collapsed
+  var bw_margin_collapsed = '.8em';
+  var ssb_width_collapsed = '.8em';
+
+  // colors used by the current theme
+  var dark_color = $('.related').css('background-color');
+  var light_color = $('.document').css('background-color');
+
+  function sidebar_is_collapsed() {
+    return sidebarwrapper.is(':not(:visible)');
+  }
+
+  function toggle_sidebar() {
+    if (sidebar_is_collapsed())
+      expand_sidebar();
+    else
+      collapse_sidebar();
+  }
+
+  function collapse_sidebar() {
+    sidebarwrapper.hide();
+    sidebar.css('width', ssb_width_collapsed);
+    bodywrapper.css('margin-left', bw_margin_collapsed);
+    sidebarbutton.css({
+        'margin-left': '0',
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('»');
+    sidebarbutton.attr('title', _('Expand sidebar'));
+    document.cookie = 'sidebar=collapsed';
+  }
+
+  function expand_sidebar() {
+    bodywrapper.css('margin-left', bw_margin_expanded);
+    sidebar.css('width', ssb_width_expanded);
+    sidebarwrapper.show();
+    sidebarbutton.css({
+        'margin-left': ssb_width_expanded-12,
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('«');
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    document.cookie = 'sidebar=expanded';
+  }
+
+  function add_sidebar_button() {
+    sidebarwrapper.css({
+        'float': 'left',
+        'margin-right': '0',
+        'width': ssb_width_expanded - 28
+    });
+    // create the button
+    sidebar.append(
+        '<div id="sidebarbutton"><span>«</span></div>'
+    );
+    var sidebarbutton = $('#sidebarbutton');
+    light_color = sidebarbutton.css('background-color');
+    // find the height of the viewport to center the '<<' in the page
+    var viewport_height;
+    if (window.innerHeight)
+ 	  viewport_height = window.innerHeight;
+    else
+	  viewport_height = $(window).height();
+    sidebarbutton.find('span').css({
+        'display': 'block',
+        'margin-top': (viewport_height - sidebar.position().top - 20) / 2
+    });
+
+    sidebarbutton.click(toggle_sidebar);
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    sidebarbutton.css({
+        'color': '#FFFFFF',
+        'border-left': '1px solid ' + dark_color,
+        'font-size': '1.2em',
+        'cursor': 'pointer',
+        'height': bodywrapper.height(),
+        'padding-top': '1px',
+        'margin-left': ssb_width_expanded - 12
+    });
+
+    sidebarbutton.hover(
+      function () {
+          $(this).css('background-color', dark_color);
+      },
+      function () {
+          $(this).css('background-color', light_color);
+      }
+    );
+  }
+
+  function set_position_from_cookie() {
+    if (!document.cookie)
+      return;
+    var items = document.cookie.split(';');
+    for(var k=0; k<items.length; k++) {
+      var key_val = items[k].split('=');
+      var key = key_val[0];
+      if (key == 'sidebar') {
+        var value = key_val[1];
+        if ((value == 'collapsed') && (!sidebar_is_collapsed()))
+          collapse_sidebar();
+        else if ((value == 'expanded') && (sidebar_is_collapsed()))
+          expand_sidebar();
+      }
+    }
+  }
+
+  add_sidebar_button();
+  var sidebarbutton = $('#sidebarbutton');
+  set_position_from_cookie();
+});
diff --git a/lib3/Mako-0.7.3/doc/_static/site.css b/lib3/Mako-0.7.3/doc/_static/site.css
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/site.css
@@ -0,0 +1,86 @@
+body {
+    font-family: Tahoma, Geneva, sans-serif;
+    line-height:1.4em;
+    margin:15px;
+    background-color:#FFFFFF;
+}
+img {border:none;}
+a { text-decoration: none;}
+a:visited  { color: #2929ff;}
+a:hover { color: #0000ff;}
+
+#wrap {
+    margin:0 auto;
+    max-width:1024px;
+    min-width:480px;
+    position:relative;
+
+}
+h1 {
+    font-size:1.6em;
+    font-weight:bold;
+}
+
+h2 {
+    font-size:1.1em;
+    font-weight:bold;
+    margin:10px 0px 10px 0px;
+}
+
+.clearfix{
+    clear:both;
+}
+
+.red {
+	font-weight:bold;
+	color:#FF0000;
+}
+.rightbar {
+    float:right;
+}
+.slogan {
+    margin-top:10px;
+}
+#gittip_nav {
+    float:right;
+    margin:10px 0px 0px 0px;
+}
+
+.toolbar {
+    margin-top:20px;
+}
+.copyright {
+    font-size:.8em;
+    text-align:center;
+    color:909090;
+}
+.pylogo {
+	text-align:right;
+	float:right;
+}
+.code {
+    font-family:monospace;
+}
+
+li {
+    margin:1px 0px 1px 0px;
+}
+
+.speedchart td {
+    font-size:small;
+}
+
+pre.codesample {
+    margin: 1.5em;
+    padding: .5em;
+    font-size: .95em;
+    line-height:1em;
+    background-color: #eee;
+    border: 1px solid #ccc;
+    width:450px;
+    overflow:auto;
+}
+
+#speedchart {
+    margin:5px 10px 5px 10px;
+}
diff --git a/lib3/Mako-0.7.3/doc/_static/underscore.js b/lib3/Mako-0.7.3/doc/_static/underscore.js
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/underscore.js
@@ -0,0 +1,23 @@
+// Underscore.js 0.5.5
+// (c) 2009 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the terms of the MIT license.
+// Portions of Underscore are inspired by or borrowed from Prototype.js,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore/
+(function(){var j=this,n=j._,i=function(a){this._wrapped=a},m=typeof StopIteration!=="undefined"?StopIteration:"__break__",b=j._=function(a){return new i(a)};if(typeof exports!=="undefined")exports._=b;var k=Array.prototype.slice,o=Array.prototype.unshift,p=Object.prototype.toString,q=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;b.VERSION="0.5.5";b.each=function(a,c,d){try{if(a.forEach)a.forEach(c,d);else if(b.isArray(a)||b.isArguments(a))for(var e=0,f=a.length;e<f;e++)c.call(d,
+a[e],e,a);else{var g=b.keys(a);f=g.length;for(e=0;e<f;e++)c.call(d,a[g[e]],g[e],a)}}catch(h){if(h!=m)throw h;}return a};b.map=function(a,c,d){if(a&&b.isFunction(a.map))return a.map(c,d);var e=[];b.each(a,function(f,g,h){e.push(c.call(d,f,g,h))});return e};b.reduce=function(a,c,d,e){if(a&&b.isFunction(a.reduce))return a.reduce(b.bind(d,e),c);b.each(a,function(f,g,h){c=d.call(e,c,f,g,h)});return c};b.reduceRight=function(a,c,d,e){if(a&&b.isFunction(a.reduceRight))return a.reduceRight(b.bind(d,e),c);
+var f=b.clone(b.toArray(a)).reverse();b.each(f,function(g,h){c=d.call(e,c,g,h,a)});return c};b.detect=function(a,c,d){var e;b.each(a,function(f,g,h){if(c.call(d,f,g,h)){e=f;b.breakLoop()}});return e};b.select=function(a,c,d){if(a&&b.isFunction(a.filter))return a.filter(c,d);var e=[];b.each(a,function(f,g,h){c.call(d,f,g,h)&&e.push(f)});return e};b.reject=function(a,c,d){var e=[];b.each(a,function(f,g,h){!c.call(d,f,g,h)&&e.push(f)});return e};b.all=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.every))return a.every(c,
+d);var e=true;b.each(a,function(f,g,h){(e=e&&c.call(d,f,g,h))||b.breakLoop()});return e};b.any=function(a,c,d){c=c||b.identity;if(a&&b.isFunction(a.some))return a.some(c,d);var e=false;b.each(a,function(f,g,h){if(e=c.call(d,f,g,h))b.breakLoop()});return e};b.include=function(a,c){if(b.isArray(a))return b.indexOf(a,c)!=-1;var d=false;b.each(a,function(e){if(d=e===c)b.breakLoop()});return d};b.invoke=function(a,c){var d=b.rest(arguments,2);return b.map(a,function(e){return(c?e[c]:e).apply(e,d)})};b.pluck=
+function(a,c){return b.map(a,function(d){return d[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g>=e.computed&&(e={value:f,computed:g})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};b.each(a,function(f,g,h){g=c?c.call(d,f,g,h):f;g<e.computed&&(e={value:f,computed:g})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,
+function(e,f,g){return{value:e,criteria:c.call(d,e,f,g)}}).sort(function(e,f){e=e.criteria;f=f.criteria;return e<f?-1:e>f?1:0}),"value")};b.sortedIndex=function(a,c,d){d=d||b.identity;for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?(e=g+1):(f=g)}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return a;if(b.isArguments(a))return k.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=function(a,c,d){return c&&!d?k.call(a,
+0,c):a[0]};b.rest=function(a,c,d){return k.call(a,b.isUndefined(c)||d?1:c)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.select(a,function(c){return!!c})};b.flatten=function(a){return b.reduce(a,[],function(c,d){if(b.isArray(d))return c.concat(b.flatten(d));c.push(d);return c})};b.without=function(a){var c=b.rest(arguments);return b.select(a,function(d){return!b.include(c,d)})};b.uniq=function(a,c){return b.reduce(a,[],function(d,e,f){if(0==f||(c===true?b.last(d)!=e:!b.include(d,
+e)))d.push(e);return d})};b.intersect=function(a){var c=b.rest(arguments);return b.select(b.uniq(a),function(d){return b.all(c,function(e){return b.indexOf(e,d)>=0})})};b.zip=function(){for(var a=b.toArray(arguments),c=b.max(b.pluck(a,"length")),d=new Array(c),e=0;e<c;e++)d[e]=b.pluck(a,String(e));return d};b.indexOf=function(a,c){if(a.indexOf)return a.indexOf(c);for(var d=0,e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,c){if(a.lastIndexOf)return a.lastIndexOf(c);for(var d=
+a.length;d--;)if(a[d]===c)return d;return-1};b.range=function(a,c,d){var e=b.toArray(arguments),f=e.length<=1;a=f?0:e[0];c=f?e[0]:e[1];d=e[2]||1;e=Math.ceil((c-a)/d);if(e<=0)return[];e=new Array(e);f=a;for(var g=0;1;f+=d){if((d>0?f-c:c-f)>=0)return e;e[g++]=f}};b.bind=function(a,c){var d=b.rest(arguments,2);return function(){return a.apply(c||j,d.concat(b.toArray(arguments)))}};b.bindAll=function(a){var c=b.rest(arguments);if(c.length==0)c=b.functions(a);b.each(c,function(d){a[d]=b.bind(a[d],a)});
+return a};b.delay=function(a,c){var d=b.rest(arguments,2);return setTimeout(function(){return a.apply(a,d)},c)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(b.rest(arguments)))};b.wrap=function(a,c){return function(){var d=[a].concat(b.toArray(arguments));return c.apply(c,d)}};b.compose=function(){var a=b.toArray(arguments);return function(){for(var c=b.toArray(arguments),d=a.length-1;d>=0;d--)c=[a[d].apply(this,c)];return c[0]}};b.keys=function(a){if(b.isArray(a))return b.range(0,a.length);
+var c=[];for(var d in a)q.call(a,d)&&c.push(d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=function(a){return b.select(b.keys(a),function(c){return b.isFunction(a[c])}).sort()};b.extend=function(a,c){for(var d in c)a[d]=c[d];return a};b.clone=function(a){if(b.isArray(a))return a.slice(0);return b.extend({},a)};b.tap=function(a,c){c(a);return a};b.isEqual=function(a,c){if(a===c)return true;var d=typeof a;if(d!=typeof c)return false;if(a==c)return true;if(!a&&c||a&&!c)return false;
+if(a.isEqual)return a.isEqual(c);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return true;if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return false;if(a.length&&a.length!==c.length)return false;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return false;for(var f in a)if(!b.isEqual(a[f],c[f]))return false;return true};b.isEmpty=function(a){return b.keys(a).length==
+0};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=function(a){return!!(a&&a.concat&&a.unshift)};b.isArguments=function(a){return a&&b.isNumber(a.length)&&!b.isArray(a)&&!r.call(a,"length")};b.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return p.call(a)==="[object Number]"};b.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};b.isRegExp=function(a){return!!(a&&
+a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};b.isNaN=function(a){return b.isNumber(a)&&isNaN(a)};b.isNull=function(a){return a===null};b.isUndefined=function(a){return typeof a=="undefined"};b.noConflict=function(){j._=n;return this};b.identity=function(a){return a};b.breakLoop=function(){throw m;};var s=0;b.uniqueId=function(a){var c=s++;return a?a+c:c};b.template=function(a,c){a=new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+a.replace(/[\r\t\n]/g,
+" ").replace(/'(?=[^%]*%>)/g,"\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g,"',$1,'").split("<%").join("');").split("%>").join("p.push('")+"');}return p.join('');");return c?a(c):a};b.forEach=b.each;b.foldl=b.inject=b.reduce;b.foldr=b.reduceRight;b.filter=b.select;b.every=b.all;b.some=b.any;b.head=b.first;b.tail=b.rest;b.methods=b.functions;var l=function(a,c){return c?b(a).chain():a};b.each(b.functions(b),function(a){var c=b[a];i.prototype[a]=function(){var d=b.toArray(arguments);
+o.call(d,this._wrapped);return l(c.apply(b,d),this._chain)}});b.each(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){c.apply(this._wrapped,arguments);return l(this._wrapped,this._chain)}});b.each(["concat","join","slice"],function(a){var c=Array.prototype[a];i.prototype[a]=function(){return l(c.apply(this._wrapped,arguments),this._chain)}});i.prototype.chain=function(){this._chain=true;return this};i.prototype.value=function(){return this._wrapped}})();
diff --git a/lib3/Mako-0.7.3/doc/_static/up-pressed.png b/lib3/Mako-0.7.3/doc/_static/up-pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..8bd587afee2fe38989383ff82010147ea56b93dd
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/up.png b/lib3/Mako-0.7.3/doc/_static/up.png
new file mode 100644
index 0000000000000000000000000000000000000000..b94625680b4a4b9647c3a6f3f283776930696aa9
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/_static/websupport.js b/lib3/Mako-0.7.3/doc/_static/websupport.js
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/_static/websupport.js
@@ -0,0 +1,808 @@
+/*
+ * websupport.js
+ * ~~~~~~~~~~~~~
+ *
+ * sphinx.websupport utilties for all documentation.
+ *
+ * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+(function($) {
+  $.fn.autogrow = function() {
+    return this.each(function() {
+    var textarea = this;
+
+    $.fn.autogrow.resize(textarea);
+
+    $(textarea)
+      .focus(function() {
+        textarea.interval = setInterval(function() {
+          $.fn.autogrow.resize(textarea);
+        }, 500);
+      })
+      .blur(function() {
+        clearInterval(textarea.interval);
+      });
+    });
+  };
+
+  $.fn.autogrow.resize = function(textarea) {
+    var lineHeight = parseInt($(textarea).css('line-height'), 10);
+    var lines = textarea.value.split('\n');
+    var columns = textarea.cols;
+    var lineCount = 0;
+    $.each(lines, function() {
+      lineCount += Math.ceil(this.length / columns) || 1;
+    });
+    var height = lineHeight * (lineCount + 1);
+    $(textarea).css('height', height);
+  };
+})(jQuery);
+
+(function($) {
+  var comp, by;
+
+  function init() {
+    initEvents();
+    initComparator();
+  }
+
+  function initEvents() {
+    $('a.comment-close').live("click", function(event) {
+      event.preventDefault();
+      hide($(this).attr('id').substring(2));
+    });
+    $('a.vote').live("click", function(event) {
+      event.preventDefault();
+      handleVote($(this));
+    });
+    $('a.reply').live("click", function(event) {
+      event.preventDefault();
+      openReply($(this).attr('id').substring(2));
+    });
+    $('a.close-reply').live("click", function(event) {
+      event.preventDefault();
+      closeReply($(this).attr('id').substring(2));
+    });
+    $('a.sort-option').live("click", function(event) {
+      event.preventDefault();
+      handleReSort($(this));
+    });
+    $('a.show-proposal').live("click", function(event) {
+      event.preventDefault();
+      showProposal($(this).attr('id').substring(2));
+    });
+    $('a.hide-proposal').live("click", function(event) {
+      event.preventDefault();
+      hideProposal($(this).attr('id').substring(2));
+    });
+    $('a.show-propose-change').live("click", function(event) {
+      event.preventDefault();
+      showProposeChange($(this).attr('id').substring(2));
+    });
+    $('a.hide-propose-change').live("click", function(event) {
+      event.preventDefault();
+      hideProposeChange($(this).attr('id').substring(2));
+    });
+    $('a.accept-comment').live("click", function(event) {
+      event.preventDefault();
+      acceptComment($(this).attr('id').substring(2));
+    });
+    $('a.delete-comment').live("click", function(event) {
+      event.preventDefault();
+      deleteComment($(this).attr('id').substring(2));
+    });
+    $('a.comment-markup').live("click", function(event) {
+      event.preventDefault();
+      toggleCommentMarkupBox($(this).attr('id').substring(2));
+    });
+  }
+
+  /**
+   * Set comp, which is a comparator function used for sorting and
+   * inserting comments into the list.
+   */
+  function setComparator() {
+    // If the first three letters are "asc", sort in ascending order
+    // and remove the prefix.
+    if (by.substring(0,3) == 'asc') {
+      var i = by.substring(3);
+      comp = function(a, b) { return a[i] - b[i]; };
+    } else {
+      // Otherwise sort in descending order.
+      comp = function(a, b) { return b[by] - a[by]; };
+    }
+
+    // Reset link styles and format the selected sort option.
+    $('a.sel').attr('href', '#').removeClass('sel');
+    $('a.by' + by).removeAttr('href').addClass('sel');
+  }
+
+  /**
+   * Create a comp function. If the user has preferences stored in
+   * the sortBy cookie, use those, otherwise use the default.
+   */
+  function initComparator() {
+    by = 'rating'; // Default to sort by rating.
+    // If the sortBy cookie is set, use that instead.
+    if (document.cookie.length > 0) {
+      var start = document.cookie.indexOf('sortBy=');
+      if (start != -1) {
+        start = start + 7;
+        var end = document.cookie.indexOf(";", start);
+        if (end == -1) {
+          end = document.cookie.length;
+          by = unescape(document.cookie.substring(start, end));
+        }
+      }
+    }
+    setComparator();
+  }
+
+  /**
+   * Show a comment div.
+   */
+  function show(id) {
+    $('#ao' + id).hide();
+    $('#ah' + id).show();
+    var context = $.extend({id: id}, opts);
+    var popup = $(renderTemplate(popupTemplate, context)).hide();
+    popup.find('textarea[name="proposal"]').hide();
+    popup.find('a.by' + by).addClass('sel');
+    var form = popup.find('#cf' + id);
+    form.submit(function(event) {
+      event.preventDefault();
+      addComment(form);
+    });
+    $('#s' + id).after(popup);
+    popup.slideDown('fast', function() {
+      getComments(id);
+    });
+  }
+
+  /**
+   * Hide a comment div.
+   */
+  function hide(id) {
+    $('#ah' + id).hide();
+    $('#ao' + id).show();
+    var div = $('#sc' + id);
+    div.slideUp('fast', function() {
+      div.remove();
+    });
+  }
+
+  /**
+   * Perform an ajax request to get comments for a node
+   * and insert the comments into the comments tree.
+   */
+  function getComments(id) {
+    $.ajax({
+     type: 'GET',
+     url: opts.getCommentsURL,
+     data: {node: id},
+     success: function(data, textStatus, request) {
+       var ul = $('#cl' + id);
+       var speed = 100;
+       $('#cf' + id)
+         .find('textarea[name="proposal"]')
+         .data('source', data.source);
+
+       if (data.comments.length === 0) {
+         ul.html('<li>No comments yet.</li>');
+         ul.data('empty', true);
+       } else {
+         // If there are comments, sort them and put them in the list.
+         var comments = sortComments(data.comments);
+         speed = data.comments.length * 100;
+         appendComments(comments, ul);
+         ul.data('empty', false);
+       }
+       $('#cn' + id).slideUp(speed + 200);
+       ul.slideDown(speed);
+     },
+     error: function(request, textStatus, error) {
+       showError('Oops, there was a problem retrieving the comments.');
+     },
+     dataType: 'json'
+    });
+  }
+
+  /**
+   * Add a comment via ajax and insert the comment into the comment tree.
+   */
+  function addComment(form) {
+    var node_id = form.find('input[name="node"]').val();
+    var parent_id = form.find('input[name="parent"]').val();
+    var text = form.find('textarea[name="comment"]').val();
+    var proposal = form.find('textarea[name="proposal"]').val();
+
+    if (text == '') {
+      showError('Please enter a comment.');
+      return;
+    }
+
+    // Disable the form that is being submitted.
+    form.find('textarea,input').attr('disabled', 'disabled');
+
+    // Send the comment to the server.
+    $.ajax({
+      type: "POST",
+      url: opts.addCommentURL,
+      dataType: 'json',
+      data: {
+        node: node_id,
+        parent: parent_id,
+        text: text,
+        proposal: proposal
+      },
+      success: function(data, textStatus, error) {
+        // Reset the form.
+        if (node_id) {
+          hideProposeChange(node_id);
+        }
+        form.find('textarea')
+          .val('')
+          .add(form.find('input'))
+          .removeAttr('disabled');
+	var ul = $('#cl' + (node_id || parent_id));
+        if (ul.data('empty')) {
+          $(ul).empty();
+          ul.data('empty', false);
+        }
+        insertComment(data.comment);
+        var ao = $('#ao' + node_id);
+        ao.find('img').attr({'src': opts.commentBrightImage});
+        if (node_id) {
+          // if this was a "root" comment, remove the commenting box
+          // (the user can get it back by reopening the comment popup)
+          $('#ca' + node_id).slideUp();
+        }
+      },
+      error: function(request, textStatus, error) {
+        form.find('textarea,input').removeAttr('disabled');
+        showError('Oops, there was a problem adding the comment.');
+      }
+    });
+  }
+
+  /**
+   * Recursively append comments to the main comment list and children
+   * lists, creating the comment tree.
+   */
+  function appendComments(comments, ul) {
+    $.each(comments, function() {
+      var div = createCommentDiv(this);
+      ul.append($(document.createElement('li')).html(div));
+      appendComments(this.children, div.find('ul.comment-children'));
+      // To avoid stagnating data, don't store the comments children in data.
+      this.children = null;
+      div.data('comment', this);
+    });
+  }
+
+  /**
+   * After adding a new comment, it must be inserted in the correct
+   * location in the comment tree.
+   */
+  function insertComment(comment) {
+    var div = createCommentDiv(comment);
+
+    // To avoid stagnating data, don't store the comments children in data.
+    comment.children = null;
+    div.data('comment', comment);
+
+    var ul = $('#cl' + (comment.node || comment.parent));
+    var siblings = getChildren(ul);
+
+    var li = $(document.createElement('li'));
+    li.hide();
+
+    // Determine where in the parents children list to insert this comment.
+    for(i=0; i < siblings.length; i++) {
+      if (comp(comment, siblings[i]) <= 0) {
+        $('#cd' + siblings[i].id)
+          .parent()
+          .before(li.html(div));
+        li.slideDown('fast');
+        return;
+      }
+    }
+
+    // If we get here, this comment rates lower than all the others,
+    // or it is the only comment in the list.
+    ul.append(li.html(div));
+    li.slideDown('fast');
+  }
+
+  function acceptComment(id) {
+    $.ajax({
+      type: 'POST',
+      url: opts.acceptCommentURL,
+      data: {id: id},
+      success: function(data, textStatus, request) {
+        $('#cm' + id).fadeOut('fast');
+        $('#cd' + id).removeClass('moderate');
+      },
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem accepting the comment.');
+      }
+    });
+  }
+
+  function deleteComment(id) {
+    $.ajax({
+      type: 'POST',
+      url: opts.deleteCommentURL,
+      data: {id: id},
+      success: function(data, textStatus, request) {
+        var div = $('#cd' + id);
+        if (data == 'delete') {
+          // Moderator mode: remove the comment and all children immediately
+          div.slideUp('fast', function() {
+            div.remove();
+          });
+          return;
+        }
+        // User mode: only mark the comment as deleted
+        div
+          .find('span.user-id:first')
+          .text('[deleted]').end()
+          .find('div.comment-text:first')
+          .text('[deleted]').end()
+          .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
+                ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
+          .remove();
+        var comment = div.data('comment');
+        comment.username = '[deleted]';
+        comment.text = '[deleted]';
+        div.data('comment', comment);
+      },
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem deleting the comment.');
+      }
+    });
+  }
+
+  function showProposal(id) {
+    $('#sp' + id).hide();
+    $('#hp' + id).show();
+    $('#pr' + id).slideDown('fast');
+  }
+
+  function hideProposal(id) {
+    $('#hp' + id).hide();
+    $('#sp' + id).show();
+    $('#pr' + id).slideUp('fast');
+  }
+
+  function showProposeChange(id) {
+    $('#pc' + id).hide();
+    $('#hc' + id).show();
+    var textarea = $('#pt' + id);
+    textarea.val(textarea.data('source'));
+    $.fn.autogrow.resize(textarea[0]);
+    textarea.slideDown('fast');
+  }
+
+  function hideProposeChange(id) {
+    $('#hc' + id).hide();
+    $('#pc' + id).show();
+    var textarea = $('#pt' + id);
+    textarea.val('').removeAttr('disabled');
+    textarea.slideUp('fast');
+  }
+
+  function toggleCommentMarkupBox(id) {
+    $('#mb' + id).toggle();
+  }
+
+  /** Handle when the user clicks on a sort by link. */
+  function handleReSort(link) {
+    var classes = link.attr('class').split(/\s+/);
+    for (var i=0; i<classes.length; i++) {
+      if (classes[i] != 'sort-option') {
+	by = classes[i].substring(2);
+      }
+    }
+    setComparator();
+    // Save/update the sortBy cookie.
+    var expiration = new Date();
+    expiration.setDate(expiration.getDate() + 365);
+    document.cookie= 'sortBy=' + escape(by) +
+                     ';expires=' + expiration.toUTCString();
+    $('ul.comment-ul').each(function(index, ul) {
+      var comments = getChildren($(ul), true);
+      comments = sortComments(comments);
+      appendComments(comments, $(ul).empty());
+    });
+  }
+
+  /**
+   * Function to process a vote when a user clicks an arrow.
+   */
+  function handleVote(link) {
+    if (!opts.voting) {
+      showError("You'll need to login to vote.");
+      return;
+    }
+
+    var id = link.attr('id');
+    if (!id) {
+      // Didn't click on one of the voting arrows.
+      return;
+    }
+    // If it is an unvote, the new vote value is 0,
+    // Otherwise it's 1 for an upvote, or -1 for a downvote.
+    var value = 0;
+    if (id.charAt(1) != 'u') {
+      value = id.charAt(0) == 'u' ? 1 : -1;
+    }
+    // The data to be sent to the server.
+    var d = {
+      comment_id: id.substring(2),
+      value: value
+    };
+
+    // Swap the vote and unvote links.
+    link.hide();
+    $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
+      .show();
+
+    // The div the comment is displayed in.
+    var div = $('div#cd' + d.comment_id);
+    var data = div.data('comment');
+
+    // If this is not an unvote, and the other vote arrow has
+    // already been pressed, unpress it.
+    if ((d.value !== 0) && (data.vote === d.value * -1)) {
+      $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
+      $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
+    }
+
+    // Update the comments rating in the local data.
+    data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
+    data.vote = d.value;
+    div.data('comment', data);
+
+    // Change the rating text.
+    div.find('.rating:first')
+      .text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
+
+    // Send the vote information to the server.
+    $.ajax({
+      type: "POST",
+      url: opts.processVoteURL,
+      data: d,
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem casting that vote.');
+      }
+    });
+  }
+
+  /**
+   * Open a reply form used to reply to an existing comment.
+   */
+  function openReply(id) {
+    // Swap out the reply link for the hide link
+    $('#rl' + id).hide();
+    $('#cr' + id).show();
+
+    // Add the reply li to the children ul.
+    var div = $(renderTemplate(replyTemplate, {id: id})).hide();
+    $('#cl' + id)
+      .prepend(div)
+      // Setup the submit handler for the reply form.
+      .find('#rf' + id)
+      .submit(function(event) {
+        event.preventDefault();
+        addComment($('#rf' + id));
+        closeReply(id);
+      })
+      .find('input[type=button]')
+      .click(function() {
+        closeReply(id);
+      });
+    div.slideDown('fast', function() {
+      $('#rf' + id).find('textarea').focus();
+    });
+  }
+
+  /**
+   * Close the reply form opened with openReply.
+   */
+  function closeReply(id) {
+    // Remove the reply div from the DOM.
+    $('#rd' + id).slideUp('fast', function() {
+      $(this).remove();
+    });
+
+    // Swap out the hide link for the reply link
+    $('#cr' + id).hide();
+    $('#rl' + id).show();
+  }
+
+  /**
+   * Recursively sort a tree of comments using the comp comparator.
+   */
+  function sortComments(comments) {
+    comments.sort(comp);
+    $.each(comments, function() {
+      this.children = sortComments(this.children);
+    });
+    return comments;
+  }
+
+  /**
+   * Get the children comments from a ul. If recursive is true,
+   * recursively include childrens' children.
+   */
+  function getChildren(ul, recursive) {
+    var children = [];
+    ul.children().children("[id^='cd']")
+      .each(function() {
+        var comment = $(this).data('comment');
+        if (recursive)
+          comment.children = getChildren($(this).find('#cl' + comment.id), true);
+        children.push(comment);
+      });
+    return children;
+  }
+
+  /** Create a div to display a comment in. */
+  function createCommentDiv(comment) {
+    if (!comment.displayed && !opts.moderator) {
+      return $('<div class="moderate">Thank you!  Your comment will show up '
+               + 'once it is has been approved by a moderator.</div>');
+    }
+    // Prettify the comment rating.
+    comment.pretty_rating = comment.rating + ' point' +
+      (comment.rating == 1 ? '' : 's');
+    // Make a class (for displaying not yet moderated comments differently)
+    comment.css_class = comment.displayed ? '' : ' moderate';
+    // Create a div for this comment.
+    var context = $.extend({}, opts, comment);
+    var div = $(renderTemplate(commentTemplate, context));
+
+    // If the user has voted on this comment, highlight the correct arrow.
+    if (comment.vote) {
+      var direction = (comment.vote == 1) ? 'u' : 'd';
+      div.find('#' + direction + 'v' + comment.id).hide();
+      div.find('#' + direction + 'u' + comment.id).show();
+    }
+
+    if (opts.moderator || comment.text != '[deleted]') {
+      div.find('a.reply').show();
+      if (comment.proposal_diff)
+        div.find('#sp' + comment.id).show();
+      if (opts.moderator && !comment.displayed)
+        div.find('#cm' + comment.id).show();
+      if (opts.moderator || (opts.username == comment.username))
+        div.find('#dc' + comment.id).show();
+    }
+    return div;
+  }
+
+  /**
+   * A simple template renderer. Placeholders such as <%id%> are replaced
+   * by context['id'] with items being escaped. Placeholders such as <#id#>
+   * are not escaped.
+   */
+  function renderTemplate(template, context) {
+    var esc = $(document.createElement('div'));
+
+    function handle(ph, escape) {
+      var cur = context;
+      $.each(ph.split('.'), function() {
+        cur = cur[this];
+      });
+      return escape ? esc.text(cur || "").html() : cur;
+    }
+
+    return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
+      return handle(arguments[2], arguments[1] == '%' ? true : false);
+    });
+  }
+
+  /** Flash an error message briefly. */
+  function showError(message) {
+    $(document.createElement('div')).attr({'class': 'popup-error'})
+      .append($(document.createElement('div'))
+               .attr({'class': 'error-message'}).text(message))
+      .appendTo('body')
+      .fadeIn("slow")
+      .delay(2000)
+      .fadeOut("slow");
+  }
+
+  /** Add a link the user uses to open the comments popup. */
+  $.fn.comment = function() {
+    return this.each(function() {
+      var id = $(this).attr('id').substring(1);
+      var count = COMMENT_METADATA[id];
+      var title = count + ' comment' + (count == 1 ? '' : 's');
+      var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
+      var addcls = count == 0 ? ' nocomment' : '';
+      $(this)
+        .append(
+          $(document.createElement('a')).attr({
+            href: '#',
+            'class': 'sphinx-comment-open' + addcls,
+            id: 'ao' + id
+          })
+            .append($(document.createElement('img')).attr({
+              src: image,
+              alt: 'comment',
+              title: title
+            }))
+            .click(function(event) {
+              event.preventDefault();
+              show($(this).attr('id').substring(2));
+            })
+        )
+        .append(
+          $(document.createElement('a')).attr({
+            href: '#',
+            'class': 'sphinx-comment-close hidden',
+            id: 'ah' + id
+          })
+            .append($(document.createElement('img')).attr({
+              src: opts.closeCommentImage,
+              alt: 'close',
+              title: 'close'
+            }))
+            .click(function(event) {
+              event.preventDefault();
+              hide($(this).attr('id').substring(2));
+            })
+        );
+    });
+  };
+
+  var opts = {
+    processVoteURL: '/_process_vote',
+    addCommentURL: '/_add_comment',
+    getCommentsURL: '/_get_comments',
+    acceptCommentURL: '/_accept_comment',
+    deleteCommentURL: '/_delete_comment',
+    commentImage: '/static/_static/comment.png',
+    closeCommentImage: '/static/_static/comment-close.png',
+    loadingImage: '/static/_static/ajax-loader.gif',
+    commentBrightImage: '/static/_static/comment-bright.png',
+    upArrow: '/static/_static/up.png',
+    downArrow: '/static/_static/down.png',
+    upArrowPressed: '/static/_static/up-pressed.png',
+    downArrowPressed: '/static/_static/down-pressed.png',
+    voting: false,
+    moderator: false
+  };
+
+  if (typeof COMMENT_OPTIONS != "undefined") {
+    opts = jQuery.extend(opts, COMMENT_OPTIONS);
+  }
+
+  var popupTemplate = '\
+    <div class="sphinx-comments" id="sc<%id%>">\
+      <p class="sort-options">\
+        Sort by:\
+        <a href="#" class="sort-option byrating">best rated</a>\
+        <a href="#" class="sort-option byascage">newest</a>\
+        <a href="#" class="sort-option byage">oldest</a>\
+      </p>\
+      <div class="comment-header">Comments</div>\
+      <div class="comment-loading" id="cn<%id%>">\
+        loading comments... <img src="<%loadingImage%>" alt="" /></div>\
+      <ul id="cl<%id%>" class="comment-ul"></ul>\
+      <div id="ca<%id%>">\
+      <p class="add-a-comment">Add a comment\
+        (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
+      <div class="comment-markup-box" id="mb<%id%>">\
+        reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
+        <tt>``code``</tt>, \
+        code blocks: <tt>::</tt> and an indented block after blank line</div>\
+      <form method="post" id="cf<%id%>" class="comment-form" action="">\
+        <textarea name="comment" cols="80"></textarea>\
+        <p class="propose-button">\
+          <a href="#" id="pc<%id%>" class="show-propose-change">\
+            Propose a change ▹\
+          </a>\
+          <a href="#" id="hc<%id%>" class="hide-propose-change">\
+            Propose a change ▿\
+          </a>\
+        </p>\
+        <textarea name="proposal" id="pt<%id%>" cols="80"\
+                  spellcheck="false"></textarea>\
+        <input type="submit" value="Add comment" />\
+        <input type="hidden" name="node" value="<%id%>" />\
+        <input type="hidden" name="parent" value="" />\
+      </form>\
+      </div>\
+    </div>';
+
+  var commentTemplate = '\
+    <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
+      <div class="vote">\
+        <div class="arrow">\
+          <a href="#" id="uv<%id%>" class="vote" title="vote up">\
+            <img src="<%upArrow%>" />\
+          </a>\
+          <a href="#" id="uu<%id%>" class="un vote" title="vote up">\
+            <img src="<%upArrowPressed%>" />\
+          </a>\
+        </div>\
+        <div class="arrow">\
+          <a href="#" id="dv<%id%>" class="vote" title="vote down">\
+            <img src="<%downArrow%>" id="da<%id%>" />\
+          </a>\
+          <a href="#" id="du<%id%>" class="un vote" title="vote down">\
+            <img src="<%downArrowPressed%>" />\
+          </a>\
+        </div>\
+      </div>\
+      <div class="comment-content">\
+        <p class="tagline comment">\
+          <span class="user-id"><%username%></span>\
+          <span class="rating"><%pretty_rating%></span>\
+          <span class="delta"><%time.delta%></span>\
+        </p>\
+        <div class="comment-text comment"><#text#></div>\
+        <p class="comment-opts comment">\
+          <a href="#" class="reply hidden" id="rl<%id%>">reply ▹</a>\
+          <a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\
+          <a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\
+          <a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</a>\
+          <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
+          <span id="cm<%id%>" class="moderation hidden">\
+            <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
+          </span>\
+        </p>\
+        <pre class="proposal" id="pr<%id%>">\
+<#proposal_diff#>\
+        </pre>\
+          <ul class="comment-children" id="cl<%id%>"></ul>\
+        </div>\
+        <div class="clearleft"></div>\
+      </div>\
+    </div>';
+
+  var replyTemplate = '\
+    <li>\
+      <div class="reply-div" id="rd<%id%>">\
+        <form id="rf<%id%>">\
+          <textarea name="comment" cols="80"></textarea>\
+          <input type="submit" value="Add reply" />\
+          <input type="button" value="Cancel" />\
+          <input type="hidden" name="parent" value="<%id%>" />\
+          <input type="hidden" name="node" value="" />\
+        </form>\
+      </div>\
+    </li>';
+
+  $(document).ready(function() {
+    init();
+  });
+})(jQuery);
+
+$(document).ready(function() {
+  // add comment anchors for all paragraphs that are commentable
+  $('.sphinx-has-comment').comment();
+
+  // highlight search words in search results
+  $("div.context").each(function() {
+    var params = $.getQueryParameters();
+    var terms = (params.q) ? params.q[0].split(/\s+/) : [];
+    var result = $(this);
+    $.each(terms, function() {
+      result.highlightText(this.toLowerCase(), 'highlighted');
+    });
+  });
+
+  // directly open comment window if requested
+  var anchor = document.location.hash;
+  if (anchor.substring(0, 9) == '#comment-') {
+    $('#ao' + anchor.substring(9)).click();
+    document.location.hash = '#s' + anchor.substring(9);
+  }
+});
diff --git a/lib3/Mako-0.7.3/doc/build/Makefile b/lib3/Mako-0.7.3/doc/build/Makefile
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/Makefile
@@ -0,0 +1,137 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = output
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest dist-html site-mako
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dist-html  same as html, but places files in /doc"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html -A mako_layout=html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dist-html:
+	$(SPHINXBUILD) -b html -A mako_layout=html $(ALLSPHINXOPTS) ..
+	@echo
+	@echo "Build finished.  The HTML pages are in ../."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SQLAlchemy.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SQLAlchemy.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/SQLAlchemy"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SQLAlchemy"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	cp texinputs/* $(BUILDDIR)/latex/
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	make -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) .
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/lib3/Mako-0.7.3/doc/build/builder/__init__.py b/lib3/Mako-0.7.3/doc/build/builder/__init__.py
new file mode 100644
diff --git a/lib3/Mako-0.7.3/doc/build/builder/builders.py b/lib3/Mako-0.7.3/doc/build/builder/builders.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/builder/builders.py
@@ -0,0 +1,97 @@
+from sphinx.application import TemplateBridge
+from sphinx.builders.html import StandaloneHTMLBuilder
+from sphinx.highlighting import PygmentsBridge
+from sphinx.jinja2glue import BuiltinTemplateLoader
+from pygments import highlight
+from pygments.lexer import RegexLexer, bygroups, using
+from pygments.token import *
+from pygments.filter import Filter, apply_filters
+from pygments.lexers import PythonLexer, PythonConsoleLexer
+from pygments.formatters import HtmlFormatter, LatexFormatter
+import re
+import os
+from mako.lookup import TemplateLookup
+from mako.template import Template
+from mako.ext.pygmentplugin import MakoLexer
+
+rtd = os.environ.get('READTHEDOCS', None) == 'True'
+
+class MakoBridge(TemplateBridge):
+    def init(self, builder, *args, **kw):
+        self.jinja2_fallback = BuiltinTemplateLoader()
+        self.jinja2_fallback.init(builder, *args, **kw)
+
+        builder.config.html_context['site_base'] = builder.config['site_base']
+
+        self.lookup = TemplateLookup(
+            directories=builder.config.templates_path,
+            imports=[
+                "from builder import util"
+            ]
+        )
+
+    def render(self, template, context):
+        template = template.replace(".html", ".mako")
+        context['prevtopic'] = context.pop('prev', None)
+        context['nexttopic'] = context.pop('next', None)
+
+        # RTD layout
+        if rtd:
+            # add variables if not present, such 
+            # as if local test of READTHEDOCS variable
+            if 'MEDIA_URL' not in context:
+                context['MEDIA_URL'] = "http://media.readthedocs.org/"
+            if 'slug' not in context:
+                context['slug'] = "mako-test-slug"
+            if 'url' not in context:
+                context['url'] = "/some/test/url"
+            if 'current_version' not in context:
+                context['current_version'] = "some_version"
+            if 'versions' not in context:
+                context['versions'] = [('default', '/default/')]
+
+            context['docs_base'] = "http://readthedocs.org"
+            context['toolbar'] = True
+            context['layout'] = "rtd_layout.mako"
+            context['pdf_url'] = "%spdf/%s/%s/%s.pdf" % (
+                    context['MEDIA_URL'],
+                    context['slug'],
+                    context['current_version'],
+                    context['slug']
+            )
+        # local docs layout
+        else:
+            context['toolbar'] = False
+            context['docs_base'] = "/"
+            context['layout'] = "layout.mako"
+
+        context.setdefault('_', lambda x:x)
+        return self.lookup.get_template(template).render_unicode(**context)
+
+    def render_string(self, template, context):
+        # this is used for  .js, .css etc. and we don't have
+        # local copies of that stuff here so use the jinja render.
+        return self.jinja2_fallback.render_string(template, context)
+
+class StripDocTestFilter(Filter):
+    def filter(self, lexer, stream):
+        for ttype, value in stream:
+            if ttype is Token.Comment and re.match(r'#\s*doctest:', value):
+                continue
+            yield ttype, value
+
+
+def autodoc_skip_member(app, what, name, obj, skip, options):
+    if what == 'class' and skip and name == '__init__':
+        return False
+    else:
+        return skip
+
+def setup(app):
+#    app.connect('autodoc-skip-member', autodoc_skip_member)
+    # Mako is already in Pygments, adding the local
+    # lexer here so that the latest syntax is available
+    app.add_lexer('mako', MakoLexer())
+    app.add_config_value('site_base', "", True)
+ 
+ 
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/doc/build/builder/util.py b/lib3/Mako-0.7.3/doc/build/builder/util.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/builder/util.py
@@ -0,0 +1,12 @@
+import re
+
+def striptags(text):
+    return re.compile(r'<[^>]*>').sub('', text)
+
+def go(m):
+    # .html with no anchor if present, otherwise "#" for top of page
+    return m.group(1) or '#'
+ 
+def strip_toplevel_anchors(text):
+    return re.compile(r'(\.html)?#[-\w]+-toplevel').sub(go, text)
+ 
diff --git a/lib3/Mako-0.7.3/doc/build/caching.rst b/lib3/Mako-0.7.3/doc/build/caching.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/caching.rst
@@ -0,0 +1,393 @@
+.. _caching_toplevel:
+
+=======
+Caching
+=======
+
+Any template or component can be cached using the ``cache``
+argument to the ``<%page>``, ``<%def>`` or ``<%block>`` directives:
+
+.. sourcecode:: mako
+
+    <%page cached="True"/>
+
+    template text
+
+The above template, after being executed the first time, will
+store its content within a cache that by default is scoped
+within memory. Subsequent calls to the template's :meth:`~.Template.render`
+method will return content directly from the cache. When the
+:class:`.Template` object itself falls out of scope, its corresponding
+cache is garbage collected along with the template.
+
+By default, caching requires that the `Beaker <http://beaker.readthedocs.org/>`_ package be installed on the
+system, however the mechanism of caching can be customized to use
+any third party or user defined system -- see :ref:`cache_plugins`.
+
+In addition to being available on the ``<%page>`` tag, the caching flag and all
+its options can be used with the ``<%def>`` tag as well:
+
+.. sourcecode:: mako
+
+    <%def name="mycomp" cached="True" cache_timeout="60">
+        other text
+    </%def>
+
+... and equivalently with the ``<%block>`` tag, anonymous or named:
+
+.. sourcecode:: mako
+
+    <%block cached="True" cache_timeout="60">
+        other text
+    </%block>
+
+Cache Arguments
+===============
+
+Mako has two cache arguments available on tags that are
+available in all cases.   The rest of the arguments
+available are specific to a backend.
+
+The two generic tags arguments are:
+
+* ``cached="True"`` - enable caching for this ``<%page>``,
+  ``<%def>``, or ``<%block>``.
+* ``cache_key`` - the "key" used to uniquely identify this content
+  in the cache.   Usually, this key is chosen automatically
+  based on the name of the rendering callable (i.e. ``body``
+  when used in ``<%page>``, the name of the def when using ``<%def>``,
+  the explicit or internally-generated name when using ``<%block>``).
+  Using the ``cache_key`` parameter, the key can be overridden
+  using a fixed or programmatically generated value.
+
+  For example, here's a page
+  that caches any page which inherits from it, based on the
+  filename of the calling template:
+
+  .. sourcecode:: mako
+
+     <%page cached="True" cache_key="${self.filename}"/>
+
+     ${next.body()}
+
+     ## rest of template
+
+On a :class:`.Template` or :class:`.TemplateLookup`, the
+caching can be configured using these arguments:
+
+* ``cache_enabled`` - Setting this
+  to ``False`` will disable all caching functionality
+  when the template renders.  Defaults to ``True``.
+  e.g.:
+
+  .. sourcecode:: python
+
+      lookup = TemplateLookup(
+                      directories='/path/to/templates',
+                      cache_enabled = False
+                      )
+
+* ``cache_impl`` - The string name of the cache backend
+  to use.   This defaults to ``'beaker'``, which has historically
+  been the only cache backend supported by Mako.
+
+  .. versionadded:: 0.6.0
+
+  For example, here's how to use the upcoming
+  `dogpile.cache <http://dogpilecache.readthedocs.org>`_
+  backend:
+
+  .. sourcecode:: python
+
+      lookup = TemplateLookup(
+                      directories='/path/to/templates',
+                      cache_impl = 'dogpile.cache',
+                      cache_args = {'regions':my_dogpile_regions}
+                      )
+
+* ``cache_args`` - A dictionary of cache parameters that
+  will be consumed by the cache backend.   See
+  :ref:`beaker_backend` for examples.
+
+  .. versionadded:: 0.6.0
+
+Backend-Specific Cache Arguments
+--------------------------------
+
+The ``<%page>``, ``<%def>``, and ``<%block>`` tags
+accept any named argument that starts with the prefix ``"cache_"``.
+Those arguments are then packaged up and passed along to the
+underlying caching implementation, minus the ``"cache_"`` prefix.
+
+The actual arguments understood are determined by the backend.
+
+* :ref:`beaker_backend` - Includes arguments understood by
+  Beaker.
+* :ref:`dogpile.cache_backend` - Includes arguments understood by
+  dogpile.cache.
+
+.. _beaker_backend:
+
+Using the Beaker Cache Backend
+------------------------------
+
+When using Beaker, new implementations will want to make usage
+of **cache regions** so that cache configurations can be maintained
+externally to templates.  These configurations live under
+named "regions" that can be referred to within templates themselves.
+
+.. versionadded:: 0.6.0
+   Support for Beaker cache regions.
+
+For example, suppose we would like two regions.  One is a "short term"
+region that will store content in a memory-based dictionary,
+expiring after 60 seconds.   The other is a Memcached region,
+where values should expire in five minutes.   To configure
+our :class:`.TemplateLookup`, first we get a handle to a
+:class:`beaker.cache.CacheManager`:
+
+.. sourcecode:: python
+
+    from beaker.cache import CacheManager
+
+    manager = CacheManager(cache_regions={
+        'short_term':{
+            'type': 'memory',
+            'expire': 60
+        },
+        'long_term':{
+            'type': 'ext:memcached',
+            'url': '127.0.0.1:11211',
+            'expire': 300
+        }
+    })
+
+    lookup = TemplateLookup(
+                    directories=['/path/to/templates'],
+                    module_directory='/path/to/modules',
+                    cache_impl='beaker',
+                    cache_args={
+                        'manager':manager
+                    }
+            )
+
+Our templates can then opt to cache data in one of either region,
+using the ``cache_region`` argument.   Such as using ``short_term``
+at the ``<%page>`` level:
+
+.. sourcecode:: mako
+
+    <%page cached="True" cache_region="short_term">
+
+    ## ...
+
+Or, ``long_term`` at the ``<%block>`` level:
+
+.. sourcecode:: mako
+
+    <%block name="header" cached="True" cache_region="long_term">
+        other text
+    </%block>
+
+The Beaker backend also works without regions.   There are a
+variety of arguments that can be passed to the ``cache_args``
+dictionary, which are also allowable in templates via the
+``<%page>``, ``<%block>``,
+and ``<%def>`` tags specific to those sections.   The values
+given override those specified at the  :class:`.TemplateLookup`
+or :class:`.Template` level.
+
+With the possible exception
+of ``cache_timeout``, these arguments are probably better off
+staying at the template configuration level.  Each argument
+specified as ``cache_XYZ`` in a template tag is specified
+without the ``cache_`` prefix in the ``cache_args`` dictionary:
+
+* ``cache_timeout`` - number of seconds in which to invalidate the
+  cached data.  After this timeout, the content is re-generated
+  on the next call.  Available as ``timeout`` in the ``cache_args``
+  dictionary.
+* ``cache_type`` - type of caching. ``'memory'``, ``'file'``, ``'dbm'``, or
+  ``'ext:memcached'`` (note that  the string ``memcached`` is
+  also accepted by the dogpile.cache Mako plugin, though not by Beaker itself).
+  Available as ``type`` in the ``cache_args`` dictionary.
+* ``cache_url`` - (only used for ``memcached`` but required) a single
+  IP address or a semi-colon separated list of IP address of
+  memcache servers to use.  Available as ``url`` in the ``cache_args``
+  dictionary.
+* ``cache_dir`` - in the case of the ``'file'`` and ``'dbm'`` cache types,
+  this is the filesystem directory with which to store data
+  files. If this option is not present, the value of
+  ``module_directory`` is used (i.e. the directory where compiled
+  template modules are stored). If neither option is available
+  an exception is thrown.  Available as ``dir`` in the
+  ``cache_args`` dictionary.
+
+.. _dogpile.cache_backend:
+
+Using the dogpile.cache Backend
+-------------------------------
+
+`dogpile.cache`_ is a new replacement for Beaker.   It provides
+a modernized, slimmed down interface and is generally easier to use
+than Beaker.   As of this writing it has not yet been released.  dogpile.cache
+includes its own Mako cache plugin -- see :mod:`dogpile.cache.plugins.mako_cache` in the
+dogpile.cache documentation.
+
+Programmatic Cache Access
+=========================
+
+The :class:`.Template`, as well as any template-derived :class:`.Namespace`, has
+an accessor called ``cache`` which returns the :class:`.Cache` object
+for that template. This object is a facade on top of the underlying
+:class:`.CacheImpl` object, and provides some very rudimental
+capabilities, such as the ability to get and put arbitrary
+values:
+
+.. sourcecode:: mako
+
+    <%
+        local.cache.set("somekey", type="memory", "somevalue")
+    %>
+
+Above, the cache associated with the ``local`` namespace is
+accessed and a key is placed within a memory cache.
+
+More commonly, the ``cache`` object is used to invalidate cached
+sections programmatically:
+
+.. sourcecode:: python
+
+    template = lookup.get_template('/sometemplate.html')
+
+    # invalidate the "body" of the template
+    template.cache.invalidate_body()
+
+    # invalidate an individual def
+    template.cache.invalidate_def('somedef')
+
+    # invalidate an arbitrary key
+    template.cache.invalidate('somekey')
+
+You can access any special method or attribute of the :class:`.CacheImpl`
+itself using the :attr:`impl <.Cache.impl>` attribute:
+
+.. sourcecode:: python
+
+    template.cache.impl.do_something_special()
+
+Note that using implementation-specific methods will mean you can't
+swap in a different kind of :class:`.CacheImpl` implementation at a
+later time.
+
+.. _cache_plugins:
+
+Cache Plugins
+=============
+
+The mechanism used by caching can be plugged in
+using a :class:`.CacheImpl` subclass.    This class implements
+the rudimental methods Mako needs to implement the caching
+API.   Mako includes the :class:`.BeakerCacheImpl` class to
+provide the default implementation.  A :class:`.CacheImpl` class
+is acquired by Mako using a ``pkg_resources`` entrypoint, using
+the name given as the ``cache_impl`` argument to :class:`.Template`
+or :class:`.TemplateLookup`.    This entry point can be
+installed via the standard `setuptools`/``setup()`` procedure, underneath
+the `EntryPoint` group named ``"mako.cache"``.  It can also be
+installed at runtime via a convenience installer :func:`.register_plugin`
+which accomplishes essentially the same task.
+
+An example plugin that implements a local dictionary cache:
+
+.. sourcecode:: python
+
+    from mako.cache import Cacheimpl, register_plugin
+
+    class SimpleCacheImpl(CacheImpl):
+        def __init__(self, cache):
+            super(SimpleCacheImpl, self).__init__(cache)
+            self._cache = {}
+
+        def get_or_create(self, key, creation_function, **kw):
+            if key in self._cache:
+                return self._cache[key]
+            else:
+                self._cache[key] = value = creation_function()
+                return value
+
+        def set(self, key, value, **kwargs):
+            self._cache[key] = value
+
+        def get(self, key, **kwargs):
+            return self._cache.get(key)
+
+        def invalidate(self, key, **kwargs):
+            self._cache.pop(key, None)
+
+    # optional - register the class locally
+    register_plugin("simple", __name__, "SimpleCacheImpl")
+
+Enabling the above plugin in a template would look like:
+
+.. sourcecode:: python
+
+    t = Template("mytemplate",
+                 file="mytemplate.html",
+                 cache_impl='simple')
+
+Guidelines for Writing Cache Plugins
+------------------------------------
+
+* The :class:`.CacheImpl` is created on a per-:class:`.Template` basis.  The
+  class should ensure that only data for the parent :class:`.Template` is
+  persisted or returned by the cache methods.    The actual :class:`.Template`
+  is available via the ``self.cache.template`` attribute.   The ``self.cache.id``
+  attribute, which is essentially the unique modulename of the template, is
+  a good value to use in order to represent a unique namespace of keys specific
+  to the template.
+* Templates only use the :meth:`.CacheImpl.get_or_create()` method
+  in an implicit fashion.  The :meth:`.CacheImpl.set`,
+  :meth:`.CacheImpl.get`, and :meth:`.CacheImpl.invalidate` methods are
+  only used in response to direct programmatic access to the corresponding
+  methods on the :class:`.Cache` object.
+* :class:`.CacheImpl` will be accessed in a multithreaded fashion if the
+  :class:`.Template` itself is used multithreaded.  Care should be taken
+  to ensure caching implementations are threadsafe.
+* A library like `Dogpile <http://pypi.python.org/pypi/dogpile.core>`_, which
+  is a minimal locking system derived from Beaker, can be used to help
+  implement the :meth:`.CacheImpl.get_or_create` method in a threadsafe
+  way that can maximize effectiveness across multiple threads as well
+  as processes. :meth:`.CacheImpl.get_or_create` is the
+  key method used by templates.
+* All arguments passed to ``**kw`` come directly from the parameters
+  inside the ``<%def>``, ``<%block>``, or ``<%page>`` tags directly,
+  minus the ``"cache_"`` prefix, as strings, with the exception of
+  the argument ``cache_timeout``, which is passed to the plugin
+  as the name ``timeout`` with the value converted to an integer.
+  Arguments present in ``cache_args`` on :class:`.Template` or
+  :class:`.TemplateLookup` are passed directly, but are superseded
+  by those present in the most specific template tag.
+* The directory where :class:`.Template` places module files can
+  be acquired using the accessor ``self.cache.template.module_directory``.
+  This directory can be a good place to throw cache-related work
+  files, underneath a prefix like ``_my_cache_work`` so that name
+  conflicts with generated modules don't occur.
+
+API Reference
+=============
+
+.. autoclass:: mako.cache.Cache
+    :members:
+    :show-inheritance:
+
+.. autoclass:: mako.cache.CacheImpl
+    :members:
+    :show-inheritance:
+
+.. autofunction:: mako.cache.register_plugin
+
+.. autoclass:: mako.ext.beaker_cache.BeakerCacheImpl
+    :members:
+    :show-inheritance:
+
diff --git a/lib3/Mako-0.7.3/doc/build/conf.py b/lib3/Mako-0.7.3/doc/build/conf.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/conf.py
@@ -0,0 +1,287 @@
+# -*- coding: utf-8 -*-
+#
+# Mako documentation build configuration file
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+sys.path.insert(0, os.path.abspath('../..'))
+sys.path.insert(0, os.path.abspath('.'))
+
+import mako
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+#extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode',
+#                'sphinx.ext.doctest', 'builder.builders']
+
+extensions = ['sphinx.ext.autodoc','sphinx.ext.intersphinx',
+                'sphinx.ext.doctest', 'builder.builders']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['templates']
+
+nitpicky = True
+
+site_base = "http://www.makotemplates.org"
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+template_bridge = "builder.builders.MakoBridge"
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'Mako'
+copyright = 'the Mako authors and contributors'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = mako.__version__
+# The full version, including alpha/beta/rc tags.
+release = mako.__version__
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'default.css'
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+html_title = "%s %s Documentation" % (project, release)
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%m/%d/%Y %H:%M:%S'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+html_domain_indices = False
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Makodoc'
+
+#autoclass_content = 'both'
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'mako_%s.tex' % release.replace('.', '_'), r'Mako Documentation',
+   r'Mike Bayer', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+# sets TOC depth to 2.
+latex_preamble = '\setcounter{tocdepth}{3}'
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+#latex_elements = {
+#    'papersize': 'letterpaper',
+#    'pointsize': '10pt',
+#}
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'mako', 'Mako Documentation',
+     ['Mako authors'], 1)
+]
+
+
+# -- Options for Epub output ---------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = 'Mako'
+epub_author = 'Mako authors'
+epub_publisher = 'Mako authors'
+epub_copyright = 'Mako authors'
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+#epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#epub_identifier = ''
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+#epub_exclude_files = []
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#epub_tocdup = True
+
+intersphinx_mapping = {
+    'dogpilecache':('http://dogpilecache.readthedocs.org/en/latest', None),
+    'beaker':('http://beaker.readthedocs.org/en/latest',None),
+}
diff --git a/lib3/Mako-0.7.3/doc/build/defs.rst b/lib3/Mako-0.7.3/doc/build/defs.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/defs.rst
@@ -0,0 +1,622 @@
+.. _defs_toplevel:
+
+===============
+Defs and Blocks
+===============
+
+``<%def>`` and ``<%block>`` are two tags that both demarcate any block of text
+and/or code.   They both exist within generated Python as a callable function,
+i.e., a Python ``def``.   They differ in their scope and calling semantics.
+Whereas ``<%def>`` provides a construct that is very much like a named Python
+``def``, the ``<%block>`` is more layout oriented.
+
+Using Defs
+==========
+
+The ``<%def>`` tag requires a ``name`` attribute, where the ``name`` references
+a Python function signature:
+
+.. sourcecode:: mako
+
+    <%def name="hello()">
+        hello world
+    </%def>
+
+To invoke the ``<%def>``, it is normally called as an expression:
+
+.. sourcecode:: mako
+
+    the def:  ${hello()}
+
+If the ``<%def>`` is not nested inside of another ``<%def>``,
+it's known as a **top level def** and can be accessed anywhere in
+the template, including above where it was defined.
+
+All defs, top level or not, have access to the current
+contextual namespace in exactly the same way their containing
+template does. Suppose the template below is executed with the
+variables ``username`` and ``accountdata`` inside the context:
+
+.. sourcecode:: mako
+
+    Hello there ${username}, how are ya.  Lets see what your account says:
+
+    ${account()}
+
+    <%def name="account()">
+        Account for ${username}:<br/>
+
+        % for row in accountdata:
+            Value: ${row}<br/>
+        % endfor
+    </%def>
+
+The ``username`` and ``accountdata`` variables are present
+within the main template body as well as the body of the
+``account()`` def.
+
+Since defs are just Python functions, you can define and pass
+arguments to them as well:
+
+.. sourcecode:: mako
+
+    ${account(accountname='john')}
+
+    <%def name="account(accountname, type='regular')">
+        account name: ${accountname}, type: ${type}
+    </%def>
+
+When you declare an argument signature for your def, they are
+required to follow normal Python conventions (i.e., all
+arguments are required except keyword arguments with a default
+value). This is in contrast to using context-level variables,
+which evaluate to ``UNDEFINED`` if you reference a name that
+does not exist.
+
+Calling Defs from Other Files
+-----------------------------
+
+Top level ``<%def>``\ s are **exported** by your template's
+module, and can be called from the outside; including from other
+templates, as well as normal Python code. Calling a ``<%def>``
+from another template is something like using an ``<%include>``
+-- except you are calling a specific function within the
+template, not the whole template.
+
+The remote ``<%def>`` call is also a little bit like calling
+functions from other modules in Python. There is an "import"
+step to pull the names from another template into your own
+template; then the function or functions are available.
+
+To import another template, use the ``<%namespace>`` tag:
+
+.. sourcecode:: mako
+
+    <%namespace name="mystuff" file="mystuff.html"/>
+
+The above tag adds a local variable ``mystuff`` to the current
+scope.
+
+Then, just call the defs off of ``mystuff``:
+
+.. sourcecode:: mako
+
+    ${mystuff.somedef(x=5,y=7)}
+
+The ``<%namespace>`` tag also supports some of the other
+semantics of Python's ``import`` statement, including pulling
+names into the local variable space, or using ``*`` to represent
+all names, using the ``import`` attribute:
+
+.. sourcecode:: mako
+
+    <%namespace file="mystuff.html" import="foo, bar"/>
+
+This is just a quick intro to the concept of a **namespace**,
+which is a central Mako concept that has its own chapter in
+these docs. For more detail and examples, see
+:ref:`namespaces_toplevel`.
+
+Calling Defs Programmatically
+-----------------------------
+
+You can call defs programmatically from any :class:`.Template` object
+using the :meth:`~.Template.get_def()` method, which returns a :class:`.DefTemplate`
+object. This is a :class:`.Template` subclass which the parent
+:class:`.Template` creates, and is usable like any other template:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    template = Template("""
+        <%def name="hi(name)">
+            hi ${name}!
+        </%def>
+
+        <%def name="bye(name)">
+            bye ${name}!
+        </%def>
+    """)
+
+    print template.get_def("hi").render(name="ed")
+    print template.get_def("bye").render(name="ed")
+
+Defs within Defs
+----------------
+
+The def model follows regular Python rules for closures.
+Declaring ``<%def>`` inside another ``<%def>`` declares it
+within the parent's **enclosing scope**:
+
+.. sourcecode:: mako
+
+    <%def name="mydef()">
+        <%def name="subdef()">
+            a sub def
+        </%def>
+
+        i'm the def, and the subcomponent is ${subdef()}
+    </%def>
+
+Just like Python, names that exist outside the inner ``<%def>``
+exist inside it as well:
+
+.. sourcecode:: mako
+
+    <%
+        x = 12
+    %>
+    <%def name="outer()">
+        <%
+            y = 15
+        %>
+        <%def name="inner()">
+            inner, x is ${x}, y is ${y}
+        </%def>
+
+        outer, x is ${x}, y is ${y}
+    </%def>
+
+Assigning to a name inside of a def declares that name as local
+to the scope of that def (again, like Python itself). This means
+the following code will raise an error:
+
+.. sourcecode:: mako
+
+    <%
+        x = 10
+    %>
+    <%def name="somedef()">
+        ## error !
+        somedef, x is ${x}
+        <%
+            x = 27
+        %>
+    </%def>
+
+...because the assignment to ``x`` declares ``x`` as local to the
+scope of ``somedef``, rendering the "outer" version unreachable
+in the expression that tries to render it.
+
+.. _defs_with_content:
+
+Calling a Def with Embedded Content and/or Other Defs
+-----------------------------------------------------
+
+A flip-side to def within def is a def call with content. This
+is where you call a def, and at the same time declare a block of
+content (or multiple blocks) that can be used by the def being
+called. The main point of such a call is to create custom,
+nestable tags, just like any other template language's
+custom-tag creation system -- where the external tag controls the
+execution of the nested tags and can communicate state to them.
+Only with Mako, you don't have to use any external Python
+modules, you can define arbitrarily nestable tags right in your
+templates.
+
+To achieve this, the target def is invoked using the form
+``<%namepacename:defname>`` instead of the normal ``${}``
+syntax. This syntax, introduced in Mako 0.2.3, is functionally
+equivalent to another tag known as ``%call``, which takes the form
+``<%call expr='namespacename.defname(args)'>``. While ``%call``
+is available in all versions of Mako, the newer style is
+probably more familiar looking. The ``namespace`` portion of the
+call is the name of the **namespace** in which the def is
+defined -- in the most simple cases, this can be ``local`` or
+``self`` to reference the current template's namespace (the
+difference between ``local`` and ``self`` is one of inheritance
+-- see :ref:`namespaces_builtin` for details).
+
+When the target def is invoked, a variable ``caller`` is placed
+in its context which contains another namespace containing the
+body and other defs defined by the caller. The body itself is
+referenced by the method ``body()``. Below, we build a ``%def``
+that operates upon ``caller.body()`` to invoke the body of the
+custom tag:
+
+.. sourcecode:: mako
+
+    <%def name="buildtable()">
+        <table>
+            <tr><td>
+                ${caller.body()}
+            </td></tr>
+        </table>
+    </%def>
+
+    <%self:buildtable>
+        I am the table body.
+    </%self:buildtable>
+
+This produces the output (whitespace formatted):
+
+.. sourcecode:: html
+
+    <table>
+        <tr><td>
+            I am the table body.
+        </td></tr>
+    </table>
+
+Using the older ``%call`` syntax looks like:
+
+.. sourcecode:: mako
+
+    <%def name="buildtable()">
+        <table>
+            <tr><td>
+                ${caller.body()}
+            </td></tr>
+        </table>
+    </%def>
+
+    <%call expr="buildtable()">
+        I am the table body.
+    </%call>
+
+The ``body()`` can be executed multiple times or not at all.
+This means you can use def-call-with-content to build iterators,
+conditionals, etc:
+
+.. sourcecode:: mako
+
+    <%def name="lister(count)">
+        % for x in range(count):
+            ${caller.body()}
+        % endfor
+    </%def>
+
+    <%self:lister count="${3}">
+        hi
+    </%self:lister>
+
+Produces:
+
+.. sourcecode:: html
+
+    hi
+    hi
+    hi
+
+Notice above we pass ``3`` as a Python expression, so that it
+remains as an integer.
+
+A custom "conditional" tag:
+
+.. sourcecode:: mako
+
+    <%def name="conditional(expression)">
+        % if expression:
+            ${caller.body()}
+        % endif
+    </%def>
+
+    <%self:conditional expression="${4==4}">
+        i'm the result
+    </%self:conditional>
+
+Produces:
+
+.. sourcecode:: html
+
+    i'm the result
+
+But that's not all. The ``body()`` function also can handle
+arguments, which will augment the local namespace of the body
+callable. The caller must define the arguments which it expects
+to receive from its target def using the ``args`` attribute,
+which is a comma-separated list of argument names. Below, our
+``<%def>`` calls the ``body()`` of its caller, passing in an
+element of data from its argument:
+
+.. sourcecode:: mako
+
+    <%def name="layoutdata(somedata)">
+        <table>
+        % for item in somedata:
+            <tr>
+            % for col in item:
+                <td>${caller.body(col=col)}</td>
+            % endfor
+            </tr>
+        % endfor
+        </table>
+    </%def>
+
+    <%self:layoutdata somedata="${[[1,2,3],[4,5,6],[7,8,9]]}" args="col">\
+    Body data: ${col}\
+    </%self:layoutdata>
+
+Produces:
+
+.. sourcecode:: html
+
+    <table>
+        <tr>
+            <td>Body data: 1</td>
+            <td>Body data: 2</td>
+            <td>Body data: 3</td>
+        </tr>
+        <tr>
+            <td>Body data: 4</td>
+            <td>Body data: 5</td>
+            <td>Body data: 6</td>
+        </tr>
+        <tr>
+            <td>Body data: 7</td>
+            <td>Body data: 8</td>
+            <td>Body data: 9</td>
+        </tr>
+    </table>
+
+You don't have to stick to calling just the ``body()`` function.
+The caller can define any number of callables, allowing the
+``<%call>`` tag to produce whole layouts:
+
+.. sourcecode:: mako
+
+    <%def name="layout()">
+        ## a layout def
+        <div class="mainlayout">
+            <div class="header">
+                ${caller.header()}
+            </div>
+
+            <div class="sidebar">
+                ${caller.sidebar()}
+            </div>
+
+            <div class="content">
+                ${caller.body()}
+            </div>
+        </div>
+    </%def>
+
+    ## calls the layout def
+    <%self:layout>
+        <%def name="header()">
+            I am the header
+        </%def>
+        <%def name="sidebar()">
+            <ul>
+                <li>sidebar 1</li>
+                <li>sidebar 2</li>
+            </ul>
+        </%def>
+
+            this is the body
+    </%self:layout>
+
+The above layout would produce:
+
+.. sourcecode:: html
+
+    <div class="mainlayout">
+        <div class="header">
+        I am the header
+        </div>
+
+        <div class="sidebar">
+        <ul>
+            <li>sidebar 1</li>
+            <li>sidebar 2</li>
+        </ul>
+        </div>
+
+        <div class="content">
+        this is the body
+        </div>
+    </div>
+
+The number of things you can do with ``<%call>`` and/or the
+``<%namespacename:defname>`` calling syntax is enormous. You can
+create form widget libraries, such as an enclosing ``<FORM>``
+tag and nested HTML input elements, or portable wrapping schemes
+using ``<div>`` or other elements. You can create tags that
+interpret rows of data, such as from a database, providing the
+individual columns of each row to a ``body()`` callable which
+lays out the row any way it wants. Basically anything you'd do
+with a "custom tag" or tag library in some other system, Mako
+provides via ``<%def>`` tags and plain Python callables which are
+invoked via ``<%namespacename:defname>`` or ``<%call>``.
+
+.. _blocks:
+
+Using Blocks
+============
+
+The ``<%block>`` tag introduces some new twists on the
+``<%def>`` tag which make it more closely tailored towards layout.
+
+.. versionadded:: 0.4.1
+
+An example of a block:
+
+.. sourcecode:: mako
+
+    <html>
+        <body>
+            <%block>
+                this is a block.
+            </%block>
+        </body>
+    </html>
+
+In the above example, we define a simple block.  The block renders its content in the place
+that it's defined.  Since the block is called for us, it doesn't need a name and the above
+is referred to as an **anonymous block**.  So the output of the above template will be:
+
+.. sourcecode:: html
+
+    <html>
+        <body>
+                this is a block.
+        </body>
+    </html>
+
+So in fact the above block has absolutely no effect.  Its usefulness comes when we start
+using modifiers.  Such as, we can apply a filter to our block:
+
+.. sourcecode:: mako
+
+    <html>
+        <body>
+            <%block filter="h">
+                <html>this is some escaped html.</html>
+            </%block>
+        </body>
+    </html>
+
+or perhaps a caching directive:
+
+.. sourcecode:: mako
+
+    <html>
+        <body>
+            <%block cached="True" cache_timeout="60">
+                This content will be cached for 60 seconds.
+            </%block>
+        </body>
+    </html>
+
+Blocks also work in iterations, conditionals, just like defs:
+
+.. sourcecode:: mako
+
+    % if some_condition:
+        <%block>condition is met</%block>
+    % endif
+
+While the block renders at the point it is defined in the template,
+the underlying function is present in the generated Python code only
+once, so there's no issue with placing a block inside of a loop or
+similar. Anonymous blocks are defined as closures in the local
+rendering body, so have access to local variable scope:
+
+.. sourcecode:: mako
+
+    % for i in range(1, 4):
+        <%block>i is ${i}</%block>
+    % endfor
+
+Using Named Blocks
+------------------
+
+Possibly the more important area where blocks are useful is when we
+do actually give them names. Named blocks are tailored to behave
+somewhat closely to Jinja2's block tag, in that they define an area
+of a layout which can be overridden by an inheriting template. In
+sharp contrast to the ``<%def>`` tag, the name given to a block is
+global for the entire template regardless of how deeply it's nested:
+
+.. sourcecode:: mako
+
+    <html>
+    <%block name="header">
+        <head>
+            <title>
+                <%block name="title">Title</%block>
+            </title>
+        </head>
+    </%block>
+    <body>
+        ${next.body()}
+    </body>
+    </html>
+
+The above example has two named blocks "``header``" and "``title``", both of which can be referred to
+by an inheriting template. A detailed walkthrough of this usage can be found at :ref:`inheritance_toplevel`.
+
+Note above that named blocks don't have any argument declaration the way defs do. They still implement themselves
+as Python functions, however, so they can be invoked additional times beyond their initial definition:
+
+.. sourcecode:: mako
+
+    <div name="page">
+        <%block name="pagecontrol">
+            <a href="">previous page</a> |
+            <a href="">next page</a>
+        </%block>
+
+        <table>
+            ## some content
+        </table>
+
+        ${pagecontrol()}
+    </div>
+
+The content referenced by ``pagecontrol`` above will be rendered both above and below the ``<table>`` tags.
+
+To keep things sane, named blocks have restrictions that defs do not:
+
+* The ``<%block>`` declaration cannot have any argument signature.
+* The name of a ``<%block>`` can only be defined once in a template -- an error is raised if two blocks of the same
+  name occur anywhere in a single template, regardless of nesting.  A similar error is raised if a top level def
+  shares the same name as that of a block.
+* A named ``<%block>`` cannot be defined within a ``<%def>``, or inside the body of a "call", i.e.
+  ``<%call>`` or ``<%namespacename:defname>`` tag.  Anonymous blocks can, however.
+
+Using Page Arguments in Named Blocks
+------------------------------------
+
+A named block is very much like a top level def. It has a similar
+restriction to these types of defs in that arguments passed to the
+template via the ``<%page>`` tag aren't automatically available.
+Using arguments with the ``<%page>`` tag is described in the section
+:ref:`namespaces_body`, and refers to scenarios such as when the
+``body()`` method of a template is called from an inherited template passing
+arguments, or the template is invoked from an ``<%include>`` tag
+with arguments. To allow a named block to share the same arguments
+passed to the page, the ``args`` attribute can be used:
+
+.. sourcecode:: mako
+
+    <%page args="post"/>
+
+    <a name="${post.title}" />
+
+    <span class="post_prose">
+        <%block name="post_prose" args="post">
+            ${post.content}
+        </%block>
+    </span>
+
+Where above, if the template is called via a directive like
+``<%include file="post.mako" args="post=post" />``, the ``post``
+variable is available both in the main body as well as the
+``post_prose`` block.
+
+Similarly, the ``**pageargs`` variable is present, in named blocks only,
+for those arguments not explicit in the ``<%page>`` tag:
+
+.. sourcecode:: mako
+
+    <%block name="post_prose">
+        ${pageargs['post'].content}
+    </%block>
+
+The ``args`` attribute is only allowed with named blocks. With
+anonymous blocks, the Python function is always rendered in the same
+scope as the call itself, so anything available directly outside the
+anonymous block is available inside as well.
diff --git a/lib3/Mako-0.7.3/doc/build/filtering.rst b/lib3/Mako-0.7.3/doc/build/filtering.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/filtering.rst
@@ -0,0 +1,344 @@
+.. _filtering_toplevel:
+
+=======================
+Filtering and Buffering
+=======================
+
+Expression Filtering
+====================
+
+As described in the chapter :ref:`syntax_toplevel`, the "``|``" operator can be
+applied to a "``${}``" expression to apply escape filters to the
+output:
+
+.. sourcecode:: mako
+
+    ${"this is some text" | u}
+
+The above expression applies URL escaping to the expression, and
+produces ``this+is+some+text``.
+
+The built-in escape flags are:
+
+* ``u`` : URL escaping, provided by
+  ``urllib.quote_plus(string.encode('utf-8'))``
+* ``h`` : HTML escaping, provided by
+  ``markupsafe.escape(string)``
+
+  .. versionadded:: 0.3.4
+     Prior versions use ``cgi.escape(string, True)``.
+
+* ``x`` : XML escaping
+* ``trim`` : whitespace trimming, provided by ``string.strip()``
+* ``entity`` : produces HTML entity references for applicable
+  strings, derived from ``htmlentitydefs``
+* ``unicode`` (``str`` on Python 3): produces a Python unicode
+  string (this function is applied by default)
+* ``decode.<some encoding>``: decode input into a Python
+  unicode with the specified encoding
+* ``n`` : disable all default filtering; only filters specified
+  in the local expression tag will be applied.
+
+To apply more than one filter, separate them by a comma:
+
+.. sourcecode:: mako
+
+    ${" <tag>some value</tag> " | h,trim}
+
+The above produces ``<tag>some value</tag>``, with
+no leading or trailing whitespace. The HTML escaping function is
+applied first, the "trim" function second.
+
+Naturally, you can make your own filters too. A filter is just a
+Python function that accepts a single string argument, and
+returns the filtered result. The expressions after the ``|``
+operator draw upon the local namespace of the template in which
+they appear, meaning you can define escaping functions locally:
+
+.. sourcecode:: mako
+
+    <%!
+        def myescape(text):
+            return "<TAG>" + text + "</TAG>"
+    %>
+
+    Here's some tagged text: ${"text" | myescape}
+
+Or from any Python module:
+
+.. sourcecode:: mako
+
+    <%!
+        import myfilters
+    %>
+
+    Here's some tagged text: ${"text" | myfilters.tagfilter}
+
+A page can apply a default set of filters to all expression tags
+using the ``expression_filter`` argument to the ``%page`` tag:
+
+.. sourcecode:: mako
+
+    <%page expression_filter="h"/>
+
+    Escaped text:  ${"<html>some html</html>"}
+
+Result:
+
+.. sourcecode:: html
+
+    Escaped text: <html>some html</html>
+
+.. _filtering_default_filters:
+
+The ``default_filters`` Argument
+--------------------------------
+
+In addition to the ``expression_filter`` argument, the
+``default_filters`` argument to both :class:`.Template` and
+:class:`.TemplateLookup` can specify filtering for all expression tags
+at the programmatic level. This array-based argument, when given
+its default argument of ``None``, will be internally set to
+``["unicode"]`` (or ``["str"]`` on Python 3), except when
+``disable_unicode=True`` is set in which case it defaults to
+``["str"]``:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], default_filters=['unicode'])
+
+To replace the usual ``unicode``/``str`` function with a
+specific encoding, the ``decode`` filter can be substituted:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], default_filters=['decode.utf8'])
+
+To disable ``default_filters`` entirely, set it to an empty
+list:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], default_filters=[])
+
+Any string name can be added to ``default_filters`` where it
+will be added to all expressions as a filter. The filters are
+applied from left to right, meaning the leftmost filter is
+applied first.
+
+.. sourcecode:: python
+
+    t = Template(templatetext, default_filters=['unicode', 'myfilter'])
+
+To ease the usage of ``default_filters`` with custom filters,
+you can also add imports (or other code) to all templates using
+the ``imports`` argument:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'],
+                       default_filters=['unicode', 'myfilter'],
+                       imports=['from mypackage import myfilter'])
+
+The above will generate templates something like this:
+
+.. sourcecode:: python
+
+    # ....
+    from mypackage import myfilter
+
+    def render_body(context):
+        context.write(myfilter(unicode("some text")))
+
+Turning off Filtering with the ``n`` Filter
+-------------------------------------------
+
+In all cases the special ``n`` filter, used locally within an
+expression, will **disable** all filters declared in the
+``<%page>`` tag as well as in ``default_filters``. Such as:
+
+.. sourcecode:: mako
+
+    ${'myexpression' | n}
+
+will render ``myexpression`` with no filtering of any kind, and:
+
+.. sourcecode:: mako
+
+    ${'myexpression' | n,trim}
+
+will render ``myexpression`` using the ``trim`` filter only.
+
+Filtering Defs and Blocks
+=========================
+
+The ``%def`` and ``%block`` tags have an argument called ``filter`` which will apply the
+given list of filter functions to the output of the ``%def``:
+
+.. sourcecode:: mako
+
+    <%def name="foo()" filter="h, trim">
+        <b>this is bold</b>
+    </%def>
+
+When the ``filter`` attribute is applied to a def as above, the def
+is automatically **buffered** as well. This is described next.
+
+Buffering
+=========
+
+One of Mako's central design goals is speed. To this end, all of
+the textual content within a template and its various callables
+is by default piped directly to the single buffer that is stored
+within the :class:`.Context` object. While this normally is easy to
+miss, it has certain side effects. The main one is that when you
+call a def using the normal expression syntax, i.e.
+``${somedef()}``, it may appear that the return value of the
+function is the content it produced, which is then delivered to
+your template just like any other expression substitution,
+except that normally, this is not the case; the return value of
+``${somedef()}`` is simply the empty string ``''``. By the time
+you receive this empty string, the output of ``somedef()`` has
+been sent to the underlying buffer.
+
+You may not want this effect, if for example you are doing
+something like this:
+
+.. sourcecode:: mako
+
+    ${" results " + somedef() + " more results "}
+
+If the ``somedef()`` function produced the content "``somedef's
+results``", the above template would produce this output:
+
+.. sourcecode:: html
+
+    somedef's results results more results
+
+This is because ``somedef()`` fully executes before the
+expression returns the results of its concatenation; the
+concatenation in turn receives just the empty string as its
+middle expression.
+
+Mako provides two ways to work around this. One is by applying
+buffering to the ``%def`` itself:
+
+.. sourcecode:: mako
+
+    <%def name="somedef()" buffered="True">
+        somedef's results
+    </%def>
+
+The above definition will generate code similar to this:
+
+.. sourcecode:: python
+
+    def somedef():
+        context.push_buffer()
+        try:
+            context.write("somedef's results")
+        finally:
+            buf = context.pop_buffer()
+        return buf.getvalue()
+
+So that the content of ``somedef()`` is sent to a second buffer,
+which is then popped off the stack and its value returned. The
+speed hit inherent in buffering the output of a def is also
+apparent.
+
+Note that the ``filter`` argument on ``%def`` also causes the def to
+be buffered. This is so that the final content of the ``%def`` can
+be delivered to the escaping function in one batch, which
+reduces method calls and also produces more deterministic
+behavior for the filtering function itself, which can possibly
+be useful for a filtering function that wishes to apply a
+transformation to the text as a whole.
+
+The other way to buffer the output of a def or any Mako callable
+is by using the built-in ``capture`` function. This function
+performs an operation similar to the above buffering operation
+except it is specified by the caller.
+
+.. sourcecode:: mako
+
+    ${" results " + capture(somedef) + " more results "}
+
+Note that the first argument to the ``capture`` function is
+**the function itself**, not the result of calling it. This is
+because the ``capture`` function takes over the job of actually
+calling the target function, after setting up a buffered
+environment. To send arguments to the function, just send them
+to ``capture`` instead:
+
+.. sourcecode:: mako
+
+    ${capture(somedef, 17, 'hi', use_paging=True)}
+
+The above call is equivalent to the unbuffered call:
+
+.. sourcecode:: mako
+
+    ${somedef(17, 'hi', use_paging=True)}
+
+Decorating
+==========
+
+.. versionadded:: 0.2.5
+
+Somewhat like a filter for a ``%def`` but more flexible, the ``decorator``
+argument to ``%def`` allows the creation of a function that will
+work in a similar manner to a Python decorator. The function can
+control whether or not the function executes. The original
+intent of this function is to allow the creation of custom cache
+logic, but there may be other uses as well.
+
+``decorator`` is intended to be used with a regular Python
+function, such as one defined in a library module. Here we'll
+illustrate the python function defined in the template for
+simplicities' sake:
+
+.. sourcecode:: mako
+
+    <%!
+        def bar(fn):
+            def decorate(context, *args, **kw):
+                context.write("BAR")
+                fn(*args, **kw)
+                context.write("BAR")
+                return ''
+            return decorate
+    %>
+
+    <%def name="foo()" decorator="bar">
+        this is foo
+    </%def>
+
+    ${foo()}
+
+The above template will return, with more whitespace than this,
+``"BAR this is foo BAR"``. The function is the render callable
+itself (or possibly a wrapper around it), and by default will
+write to the context. To capture its output, use the :func:`.capture`
+callable in the ``mako.runtime`` module (available in templates
+as just ``runtime``):
+
+.. sourcecode:: mako
+
+    <%!
+        def bar(fn):
+            def decorate(context, *args, **kw):
+                return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR"
+            return decorate
+    %>
+
+    <%def name="foo()" decorator="bar">
+        this is foo
+    </%def>
+
+    ${foo()}
+
+The decorator can be used with top-level defs as well as nested
+defs, and blocks too. Note that when calling a top-level def from the
+:class:`.Template` API, i.e. ``template.get_def('somedef').render()``,
+the decorator has to write the output to the ``context``, i.e.
+as in the first example. The return value gets discarded.
diff --git a/lib3/Mako-0.7.3/doc/build/index.rst b/lib3/Mako-0.7.3/doc/build/index.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/index.rst
@@ -0,0 +1,22 @@
+Table of Contents
+=================
+
+.. toctree::
+    :maxdepth: 2
+
+    usage
+    syntax
+    defs
+    runtime
+    namespaces
+    inheritance
+    filtering
+    unicode
+    caching
+
+Indices and Tables
+------------------
+
+* :ref:`genindex`
+* :ref:`search`
+
diff --git a/lib3/Mako-0.7.3/doc/build/inheritance.rst b/lib3/Mako-0.7.3/doc/build/inheritance.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/inheritance.rst
@@ -0,0 +1,534 @@
+.. _inheritance_toplevel:
+
+===========
+Inheritance
+===========
+
+.. note::  Most of the inheritance examples here take advantage of a feature that's
+    new in Mako as of version 0.4.1 called the "block".  This tag is very similar to
+    the "def" tag but is more streamlined for usage with inheritance.  Note that
+    all of the examples here which use blocks can also use defs instead.  Contrasting
+    usages will be illustrated.
+
+Using template inheritance, two or more templates can organize
+themselves into an **inheritance chain**, where content and
+functions from all involved templates can be intermixed. The
+general paradigm of template inheritance is this: if a template
+``A`` inherits from template ``B``, then template ``A`` agrees
+to send the executional control to template ``B`` at runtime
+(``A`` is called the **inheriting** template). Template ``B``,
+the **inherited** template, then makes decisions as to what
+resources from ``A`` shall be executed.
+
+In practice, it looks like this. Here's a hypothetical inheriting
+template, ``index.html``:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="base.html"/>
+
+    <%block name="header">
+        this is some header content
+    </%block>
+
+    this is the body content.
+
+And ``base.html``, the inherited template:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                <%block name="header"/>
+            </div>
+
+            ${self.body()}
+
+            <div class="footer">
+                <%block name="footer">
+                    this is the footer
+                </%block>
+            </div>
+        </body>
+    </html>
+
+Here is a breakdown of the execution:
+
+#. When ``index.html`` is rendered, control immediately passes to
+   ``base.html``.
+#. ``base.html`` then renders the top part of an HTML document,
+   then invokes the ``<%block name="header">`` block.  It invokes the
+   underlying ``header()`` function off of a built-in namespace
+   called ``self`` (this namespace was first introduced in the
+   :doc:`Namespaces chapter <namespaces>` in :ref:`namespace_self`). Since
+   ``index.html`` is the topmost template and also defines a block
+   called ``header``, it's this ``header`` block that ultimately gets
+   executed -- instead of the one that's present in ``base.html``.
+#. Control comes back to ``base.html``. Some more HTML is
+   rendered.
+#. ``base.html`` executes ``self.body()``. The ``body()``
+   function on all template-based namespaces refers to the main
+   body of the template, therefore the main body of
+   ``index.html`` is rendered.
+#. When ``<%block name="header">`` is encountered in ``index.html`` 
+   during the ``self.body()`` call, a conditional is checked -- does the
+   current inherited template, i.e. ``base.html``, also define this block? If yes,
+   the ``<%block>`` is **not** executed here -- the inheritance
+   mechanism knows that the parent template is responsible for rendering
+   this block (and in fact it already has).  In other words a block
+   only renders in its *basemost scope*.
+#. Control comes back to ``base.html``. More HTML is rendered,
+   then the ``<%block name="footer">`` expression is invoked.
+#. The ``footer`` block is only defined in ``base.html``, so being
+   the topmost definition of ``footer``, it's the one that
+   executes. If ``index.html`` also specified ``footer``, then
+   its version would **override** that of the base.
+#. ``base.html`` finishes up rendering its HTML and the template
+   is complete, producing:
+
+   .. sourcecode:: html
+
+        <html>
+            <body>
+                <div class="header">
+                    this is some header content
+                </div>
+
+                this is the body content.
+
+                <div class="footer">
+                    this is the footer
+                </div>
+            </body>
+        </html>
+
+...and that is template inheritance in a nutshell. The main idea
+is that the methods that you call upon ``self`` always
+correspond to the topmost definition of that method. Very much
+the way ``self`` works in a Python class, even though Mako is
+not actually using Python class inheritance to implement this
+functionality. (Mako doesn't take the "inheritance" metaphor too
+seriously; while useful to setup some commonly recognized
+semantics, a textual template is not very much like an
+object-oriented class construct in practice).
+
+Nesting Blocks
+==============
+
+The named blocks defined in an inherited template can also be nested within
+other blocks.  The name given to each block is globally accessible via any inheriting
+template.  We can add a new block ``title`` to our ``header`` block:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                <%block name="header">
+                    <h2>
+                        <%block name="title"/>
+                    </h2>
+                </%block>
+            </div>
+
+            ${self.body()}
+
+            <div class="footer">
+                <%block name="footer">
+                    this is the footer
+                </%block>
+            </div>
+        </body>
+    </html>
+
+The inheriting template can name either or both of ``header`` and ``title``, separately
+or nested themselves:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="base.html"/>
+
+    <%block name="header">
+        this is some header content
+        ${parent.header()}
+    </%block>
+
+    <%block name="title">
+        this is the title
+    </%block>
+
+    this is the body content.
+
+Note when we overrode ``header``, we added an extra call ``${parent.header()}`` in order to invoke
+the parent's ``header`` block in addition to our own.  That's described in more detail below,
+in :ref:`parent_namespace`.
+
+Rendering a Named Block Multiple Times
+======================================
+
+Recall from the section :ref:`blocks` that a named block is just like a ``<%def>``,
+with some different usage rules.  We can call one of our named sections distinctly, for example
+a section that is used more than once, such as the title of a page:
+
+.. sourcecode:: mako
+
+    <html>
+        <head>
+            <title>${self.title()}</title>
+        </head>
+        <body>
+        <%block name="header">
+            <h2><%block name="title"/></h2>
+        </%block>
+        ${self.body()}
+        </body>
+    </html>
+
+Where above an inheriting template can define ``<%block name="title">`` just once, and it will be
+used in the base template both in the ``<title>`` section as well as the ``<h2>``.
+
+But what about Defs?
+====================
+
+The previous example used the ``<%block>`` tag to produce areas of content
+to be overridden.  Before Mako 0.4.1, there wasn't any such tag -- instead
+there was only the ``<%def>`` tag.   As it turns out, named blocks and defs are
+largely interchangeable.  The def simply doesn't call itself automatically,
+and has more open-ended naming and scoping rules that are more flexible and similar
+to Python itself, but less suited towards layout.  The first example from
+this chapter using defs would look like:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="base.html"/>
+
+    <%def name="header()">
+        this is some header content
+    </%def>
+
+    this is the body content.
+
+And ``base.html``, the inherited template:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                ${self.header()}
+            </div>
+
+            ${self.body()}
+
+            <div class="footer">
+                ${self.footer()}
+            </div>
+        </body>
+    </html>
+
+    <%def name="header()"/>
+    <%def name="footer()">
+        this is the footer
+    </%def>
+
+Above, we illustrate that defs differ from blocks in that their definition
+and invocation are defined in two separate places, instead of at once. You can *almost* do exactly what a
+block does if you put the two together:
+
+.. sourcecode:: mako
+
+    <div class="header">
+        <%def name="header()"></%def>${self.header()}
+    </div>
+
+The ``<%block>`` is obviously more streamlined than the ``<%def>`` for this kind
+of usage.  In addition,
+the above "inline" approach with ``<%def>`` does not work with nesting:
+
+.. sourcecode:: mako
+
+    <head>
+        <%def name="header()">
+            <title>
+            ## this won't work !
+            <%def name="title()">default title</%def>${self.title()}
+            </title>
+        </%def>${self.header()}
+    </head>
+
+Where above, the ``title()`` def, because it's a def within a def, is not part of the
+template's exported namespace and will not be part of ``self``.  If the inherited template
+did define its own ``title`` def at the top level, it would be called, but the "default title"
+above is not present at all on ``self`` no matter what.  For this to work as expected
+you'd instead need to say:
+
+.. sourcecode:: mako
+
+    <head>
+        <%def name="header()">
+            <title>
+            ${self.title()}
+            </title>
+        </%def>${self.header()}
+
+        <%def name="title()"/>
+    </head>
+
+That is, ``title`` is defined outside of any other defs so that it is in the ``self`` namespace.
+It works, but the definition needs to be potentially far away from the point of render.
+
+A named block is always placed in the ``self`` namespace, regardless of nesting,
+so this restriction is lifted:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <head>
+        <%block name="header">
+            <title>
+            <%block name="title"/>
+            </title>
+        </%block>
+    </head>
+
+The above template defines ``title`` inside of ``header``, and an inheriting template can define
+one or both in **any** configuration, nested inside each other or not, in order for them to be used:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="base.html"/>
+    <%block name="title">
+        the title
+    </%block>
+    <%block name="header">
+        the header
+    </%block>
+
+So while the ``<%block>`` tag lifts the restriction of nested blocks not being available externally,
+in order to achieve this it *adds* the restriction that all block names in a single template need
+to be globally unique within the template, and additionally that a ``<%block>`` can't be defined
+inside of a ``<%def>``. It's a more restricted tag suited towards a more specific use case than ``<%def>``.
+
+Using the ``next`` Namespace to Produce Content Wrapping
+========================================================
+
+Sometimes you have an inheritance chain that spans more than two
+templates. Or maybe you don't, but you'd like to build your
+system such that extra inherited templates can be inserted in
+the middle of a chain where they would be smoothly integrated.
+If each template wants to define its layout just within its main
+body, you can't just call ``self.body()`` to get at the
+inheriting template's body, since that is only the topmost body.
+To get at the body of the *next* template, you call upon the
+namespace ``next``, which is the namespace of the template
+**immediately following** the current template.
+
+Lets change the line in ``base.html`` which calls upon
+``self.body()`` to instead call upon ``next.body()``:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                <%block name="header"/>
+            </div>
+
+            ${next.body()}
+
+            <div class="footer">
+                <%block name="footer">
+                    this is the footer
+                </%block>
+            </div>
+        </body>
+    </html>
+
+
+Lets also add an intermediate template called ``layout.html``,
+which inherits from ``base.html``:
+
+.. sourcecode:: mako
+
+    ## layout.html
+    <%inherit file="base.html"/>
+    <ul>
+        <%block name="toolbar">
+            <li>selection 1</li>
+            <li>selection 2</li>
+            <li>selection 3</li>
+        </%block>
+    </ul>
+    <div class="mainlayout">
+        ${next.body()}
+    </div>
+
+And finally change ``index.html`` to inherit from
+``layout.html`` instead:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="layout.html"/>
+
+    ## .. rest of template
+
+In this setup, each call to ``next.body()`` will render the body
+of the next template in the inheritance chain (which can be
+written as ``base.html -> layout.html -> index.html``). Control
+is still first passed to the bottommost template ``base.html``,
+and ``self`` still references the topmost definition of any
+particular def.
+
+The output we get would be:
+
+.. sourcecode:: html
+
+    <html>
+        <body>
+            <div class="header">
+                this is some header content
+            </div>
+
+            <ul>
+                <li>selection 1</li>
+                <li>selection 2</li>
+                <li>selection 3</li>
+            </ul>
+
+            <div class="mainlayout">
+            this is the body content.
+            </div>
+
+            <div class="footer">
+                this is the footer
+            </div>
+        </body>
+    </html>
+
+So above, we have the ``<html>``, ``<body>`` and
+``header``/``footer`` layout of ``base.html``, we have the
+``<ul>`` and ``mainlayout`` section of ``layout.html``, and the
+main body of ``index.html`` as well as its overridden ``header``
+def. The ``layout.html`` template is inserted into the middle of
+the chain without ``base.html`` having to change anything.
+Without the ``next`` namespace, only the main body of
+``index.html`` could be used; there would be no way to call
+``layout.html``'s body content.
+
+.. _parent_namespace:
+
+Using the ``parent`` Namespace to Augment Defs
+==============================================
+
+Lets now look at the other inheritance-specific namespace, the
+opposite of ``next`` called ``parent``. ``parent`` is the
+namespace of the template **immediately preceding** the current
+template. What's useful about this namespace is that
+defs or blocks can call upon their overridden versions.
+This is not as hard as it sounds and
+is very much like using the ``super`` keyword in Python. Lets
+modify ``index.html`` to augment the list of selections provided
+by the ``toolbar`` function in ``layout.html``:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="layout.html"/>
+
+    <%block name="header">
+        this is some header content
+    </%block>
+
+    <%block name="toolbar">
+        ## call the parent's toolbar first
+        ${parent.toolbar()}
+        <li>selection 4</li>
+        <li>selection 5</li>
+    </%block>
+
+    this is the body content.
+
+Above, we implemented a ``toolbar()`` function, which is meant
+to override the definition of ``toolbar`` within the inherited
+template ``layout.html``. However, since we want the content
+from that of ``layout.html`` as well, we call it via the
+``parent`` namespace whenever we want it's content, in this case
+before we add our own selections. So the output for the whole
+thing is now:
+
+.. sourcecode:: html
+
+    <html>
+        <body>
+            <div class="header">
+                this is some header content
+            </div>
+
+            <ul>
+                <li>selection 1</li>
+                <li>selection 2</li>
+                <li>selection 3</li>
+                <li>selection 4</li>
+                <li>selection 5</li>
+            </ul>
+
+            <div class="mainlayout">
+            this is the body content.
+            </div>
+
+            <div class="footer">
+                this is the footer
+            </div>
+        </body>
+    </html>
+
+and you're now a template inheritance ninja!
+
+Inheritable Attributes
+======================
+
+The :attr:`attr <.Namespace.attr>` accessor of the :class:`.Namespace` object
+allows access to module level variables declared in a template. By accessing
+``self.attr``, you can access regular attributes from the
+inheritance chain as declared in ``<%! %>`` sections. Such as:
+
+.. sourcecode:: mako
+
+    <%!
+        class_ = "grey"
+    %>
+
+    <div class="${self.attr.class_}">
+        ${self.body()}
+    </div>
+
+If an inheriting template overrides ``class_`` to be
+``"white"``, as in:
+
+.. sourcecode:: mako
+
+    <%!
+        class_ = "white"
+    %>
+    <%inherit file="parent.html"/>
+
+    This is the body
+
+you'll get output like:
+
+.. sourcecode:: html
+
+    <div class="white">
+        This is the body
+    </div>
+
diff --git a/lib3/Mako-0.7.3/doc/build/namespaces.rst b/lib3/Mako-0.7.3/doc/build/namespaces.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/namespaces.rst
@@ -0,0 +1,349 @@
+.. _namespaces_toplevel:
+
+==========
+Namespaces
+==========
+
+Namespaces are used to organize groups of defs into
+categories, and also to "import" defs from other files.
+
+If the file ``components.html`` defines these two defs:
+
+.. sourcecode:: mako
+
+    ## components.html
+    <%def name="comp1()">
+        this is comp1
+    </%def>
+
+    <%def name="comp2(x)">
+        this is comp2, x is ${x}
+    </%def>
+
+you can make another file, for example ``index.html``, that
+pulls those two defs into a namespace called ``comp``:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%namespace name="comp" file="components.html"/>
+
+    Here's comp1:  ${comp.comp1()}
+    Here's comp2:  ${comp.comp2(x=5)}
+
+The ``comp`` variable above is an instance of
+:class:`.Namespace`, a **proxy object** which delivers
+method calls to the underlying template callable using the
+current context.
+
+``<%namespace>`` also provides an ``import`` attribute which can
+be used to pull the names into the local namespace, removing the
+need to call it via the "``.``" operator. When ``import`` is used, the
+``name`` attribute is optional.
+
+.. sourcecode:: mako
+
+    <%namespace file="components.html" import="comp1, comp2"/>
+
+    Heres comp1:  ${comp1()}
+    Heres comp2:  ${comp2(x=5)}
+
+``import`` also supports the "``*``" operator:
+
+.. sourcecode:: mako
+
+    <%namespace file="components.html" import="*"/>
+
+    Heres comp1:  ${comp1()}
+    Heres comp2:  ${comp2(x=5)}
+
+The names imported by the ``import`` attribute take precedence
+over any names that exist within the current context.
+
+.. note:: In current versions of Mako, usage of ``import='*'`` is
+   known to decrease performance of the template. This will be
+   fixed in a future release.
+
+The ``file`` argument allows expressions -- if looking for
+context variables, the ``context`` must be named explicitly:
+
+.. sourcecode:: mako
+
+    <%namespace name="dyn" file="${context['namespace_name']}"/>
+
+Ways to Call Namespaces
+=======================
+
+There are essentially four ways to call a function from a
+namespace.
+
+The "expression" format, as described previously. Namespaces are
+just Python objects with functions on them, and can be used in
+expressions like any other function:
+
+.. sourcecode:: mako
+
+    ${mynamespace.somefunction('some arg1', 'some arg2', arg3='some arg3', arg4='some arg4')}
+
+Synonymous with the "expression" format is the "custom tag"
+format, when a "closed" tag is used. This format, introduced in
+Mako 0.2.3, allows the usage of a "custom" Mako tag, with the
+function arguments passed in using named attributes:
+
+.. sourcecode:: mako
+
+    <%mynamespace:somefunction arg1="some arg1" arg2="some arg2" arg3="some arg3" arg4="some arg4"/>
+
+When using tags, the values of the arguments are taken as
+literal strings by default. To embed Python expressions as
+arguments, use the embedded expression format:
+
+.. sourcecode:: mako
+
+    <%mynamespace:somefunction arg1="${someobject.format()}" arg2="${somedef(5, 12)}"/>
+
+The "custom tag" format is intended mainly for namespace
+functions which recognize body content, which in Mako is known
+as a "def with embedded content":
+
+.. sourcecode:: mako
+
+    <%mynamespace:somefunction arg1="some argument" args="x, y">
+        Some record: ${x}, ${y}
+    </%mynamespace:somefunction>
+
+The "classic" way to call defs with embedded content is the ``<%call>`` tag:
+
+.. sourcecode:: mako
+
+    <%call expr="mynamespace.somefunction(arg1='some argument')" args="x, y">
+        Some record: ${x}, ${y}
+    </%call>
+
+For information on how to construct defs that embed content from
+the caller, see :ref:`defs_with_content`.
+
+.. _namespaces_python_modules:
+
+Namespaces from Regular Python Modules
+======================================
+
+Namespaces can also import regular Python functions from
+modules. These callables need to take at least one argument,
+``context``, an instance of :class:`.Context`. A module file 
+``some/module.py`` might contain the callable:
+
+.. sourcecode:: python
+
+    def my_tag(context):
+        context.write("hello world")
+        return ''
+
+A template can use this module via:
+
+.. sourcecode:: mako
+
+    <%namespace name="hw" module="some.module"/>
+
+    ${hw.my_tag()}
+
+Note that the ``context`` argument is not needed in the call;
+the :class:`.Namespace` tag creates a locally-scoped callable which
+takes care of it. The ``return ''`` is so that the def does not
+dump a ``None`` into the output stream -- the return value of any
+def is rendered after the def completes, in addition to whatever
+was passed to :meth:`.Context.write` within its body.
+
+If your def is to be called in an "embedded content" context,
+that is as described in :ref:`defs_with_content`, you should use
+the :func:`.supports_caller` decorator, which will ensure that Mako
+will ensure the correct "caller" variable is available when your
+def is called, supporting embedded content:
+
+.. sourcecode:: python
+
+    from mako.runtime import supports_caller
+
+    @supports_caller
+    def my_tag(context):
+        context.write("<div>")
+        context['caller'].body()
+        context.write("</div>")
+        return ''
+
+Capturing of output is available as well, using the
+outside-of-templates version of the :func:`.capture` function,
+which accepts the "context" as its first argument:
+
+.. sourcecode:: python
+
+    from mako.runtime import supports_caller, capture
+
+    @supports_caller
+    def my_tag(context):
+        return "<div>%s</div>" % \
+                capture(context, context['caller'].body, x="foo", y="bar")
+
+Declaring Defs in Namespaces
+============================
+
+The ``<%namespace>`` tag supports the definition of ``<%def>``\ s
+directly inside the tag. These defs become part of the namespace
+like any other function, and will override the definitions
+pulled in from a remote template or module:
+
+.. sourcecode:: mako
+
+    ## define a namespace
+    <%namespace name="stuff">
+        <%def name="comp1()">
+            comp1
+        </%def>
+    </%namespace>
+
+    ## then call it
+    ${stuff.comp1()}
+
+.. _namespaces_body:
+
+The ``body()`` Method
+=====================
+
+Every namespace that is generated from a template contains a
+method called ``body()``. This method corresponds to the main
+body of the template, and plays its most important roles when
+using inheritance relationships as well as
+def-calls-with-content.
+
+Since the ``body()`` method is available from a namespace just
+like all the other defs defined in a template, what happens if
+you send arguments to it? By default, the ``body()`` method
+accepts no positional arguments, and for usefulness in
+inheritance scenarios will by default dump all keyword arguments
+into a dictionary called ``pageargs``. But if you actually want
+to get at the keyword arguments, Mako recommends you define your
+own argument signature explicitly. You do this via using the
+``<%page>`` tag:
+
+.. sourcecode:: mako
+
+    <%page args="x, y, someval=8, scope='foo', **kwargs"/>
+
+A template which defines the above signature requires that the
+variables ``x`` and ``y`` are defined, defines default values
+for ``someval`` and ``scope``, and sets up ``**kwargs`` to
+receive all other keyword arguments. If ``**kwargs`` or similar
+is not present, the argument ``**pageargs`` gets tacked on by
+Mako. When the template is called as a top-level template (i.e.
+via :meth:`~.Template.render`) or via the ``<%include>`` tag, the
+values for these arguments will be pulled from the ``Context``.
+In all other cases, i.e. via calling the ``body()`` method, the
+arguments are taken as ordinary arguments from the method call.
+So above, the body might be called as:
+
+.. sourcecode:: mako
+
+    ${self.body(5, y=10, someval=15, delta=7)}
+
+The :class:`.Context` object also supplies a :attr:`~.Context.kwargs` accessor, for
+cases when you'd like to pass along whatever is in the context to
+a ``body()`` callable:
+
+.. sourcecode:: mako
+
+    ${next.body(**context.kwargs)}
+
+The usefulness of calls like the above become more apparent when
+one works with inheriting templates. For more information on
+this, as well as the meanings of the names ``self`` and
+``next``, see :ref:`inheritance_toplevel`.
+
+.. _namespaces_builtin:
+
+Built-in Namespaces
+===================
+
+The namespace is so great that Mako gives your template one (or
+two) for free. The names of these namespaces are ``local`` and
+``self``. Other built-in namespaces include ``parent`` and
+``next``, which are optional and are described in
+:ref:`inheritance_toplevel`.
+
+.. _namespace_local:
+
+``local``
+---------
+
+The ``local`` namespace is basically the namespace for the
+currently executing template. This means that all of the top
+level defs defined in your template, as well as your template's
+``body()`` function, are also available off of the ``local``
+namespace.
+
+The ``local`` namespace is also where properties like ``uri``,
+``filename``, and ``module`` and the ``get_namespace`` method
+can be particularly useful.
+
+.. _namespace_self:
+
+``self``
+--------
+
+The ``self`` namespace, in the case of a template that does not
+use inheritance, is synonymous with ``local``. If inheritance is
+used, then ``self`` references the topmost template in the
+inheritance chain, where it is most useful for providing the
+ultimate form of various "method" calls which may have been
+overridden at various points in an inheritance chain. See
+:ref:`inheritance_toplevel`.
+
+Inheritable Namespaces
+======================
+
+The ``<%namespace>`` tag includes an optional attribute
+``inheritable="True"``, which will cause the namespace to be
+attached to the ``self`` namespace. Since ``self`` is globally
+available throughout an inheritance chain (described in the next
+section), all the templates in an inheritance chain can get at
+the namespace imported in a super-template via ``self``.
+
+.. sourcecode:: mako
+
+    ## base.html
+    <%namespace name="foo" file="foo.html" inheritable="True"/>
+
+    ${next.body()}
+
+    ## somefile.html
+    <%inherit file="base.html"/>
+
+    ${self.foo.bar()}
+
+This allows a super-template to load a whole bunch of namespaces
+that its inheriting templates can get to, without them having to
+explicitly load those namespaces themselves.
+
+The ``import="*"`` part of the ``<%namespace>`` tag doesn't yet
+interact with the ``inheritable`` flag, so currently you have to
+use the explicit namespace name off of ``self``, followed by the
+desired function name. But more on this in a future release.
+
+API Reference
+=============
+
+.. autoclass:: mako.runtime.Namespace
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.runtime.TemplateNamespace
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.runtime.ModuleNamespace
+    :show-inheritance:
+    :members:
+ 
+.. autofunction:: mako.runtime.supports_caller
+
+.. autofunction:: mako.runtime.capture
+
diff --git a/lib3/Mako-0.7.3/doc/build/runtime.rst b/lib3/Mako-0.7.3/doc/build/runtime.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/runtime.rst
@@ -0,0 +1,448 @@
+.. _runtime_toplevel:
+
+============================
+The Mako Runtime Environment
+============================
+
+This section describes a little bit about the objects and
+built-in functions that are available in templates.
+
+.. _context:
+
+Context
+=======
+
+The :class:`.Context` is the central object that is created when
+a template is first executed, and is responsible for handling
+all communication with the outside world.  Within the template
+environment, it is available via the :ref:`reserved name <reserved_names>`
+``context``.  The :class:`.Context` includes two
+major components, one of which is the output buffer, which is a
+file-like object such as Python's ``StringIO`` or similar, and
+the other a dictionary of variables that can be freely
+referenced within a template; this dictionary is a combination
+of the arguments sent to the :meth:`~.Template.render` function and
+some built-in variables provided by Mako's runtime environment.
+
+The Buffer
+----------
+
+The buffer is stored within the :class:`.Context`, and writing
+to it is achieved by calling the :meth:`~.Context.write` method
+-- in a template this looks like ``context.write('some string')``.
+You usually don't need to care about this, as all text within a template, as
+well as all expressions provided by ``${}``, automatically send
+everything to this method. The cases you might want to be aware
+of its existence are if you are dealing with various
+filtering/buffering scenarios, which are described in
+:ref:`filtering_toplevel`, or if you want to programmatically
+send content to the output stream, such as within a ``<% %>``
+block.
+
+.. sourcecode:: mako
+
+    <%
+        context.write("some programmatic text")
+    %>
+
+The actual buffer may or may not be the original buffer sent to
+the :class:`.Context` object, as various filtering/caching
+scenarios may "push" a new buffer onto the context's underlying
+buffer stack. For this reason, just stick with
+``context.write()`` and content will always go to the topmost
+buffer.
+
+.. _context_vars:
+
+Context Variables
+-----------------
+
+When your template is compiled into a Python module, the body
+content is enclosed within a Python function called
+``render_body``. Other top-level defs defined in the template are
+defined within their own function bodies which are named after
+the def's name with the prefix ``render_`` (i.e. ``render_mydef``).
+One of the first things that happens within these functions is
+that all variable names that are referenced within the function
+which are not defined in some other way (i.e. such as via
+assignment, module level imports, etc.) are pulled from the
+:class:`.Context` object's dictionary of variables. This is how you're
+able to freely reference variable names in a template which
+automatically correspond to what was passed into the current
+:class:`.Context`.
+
+* **What happens if I reference a variable name that is not in
+  the current context?** - The value you get back is a special
+  value called ``UNDEFINED``, or if the ``strict_undefined=True`` flag
+  is used a ``NameError`` is raised. ``UNDEFINED`` is just a simple global
+  variable with the class :class:`mako.runtime.Undefined`. The
+  ``UNDEFINED`` object throws an error when you call ``str()`` on
+  it, which is what happens if you try to use it in an
+  expression.
+* **UNDEFINED makes it hard for me to find what name is missing** - An alternative
+  is to specify the option ``strict_undefined=True``
+  to the :class:`.Template` or :class:`.TemplateLookup`.  This will cause
+  any non-present variables to raise an immediate ``NameError``
+  which includes the name of the variable in its message
+  when :meth:`~.Template.render` is called -- ``UNDEFINED`` is not used.
+
+  .. versionadded:: 0.3.6
+
+* **Why not just return None?** Using ``UNDEFINED``, or
+  raising a ``NameError`` is more
+  explicit and allows differentiation between a value of ``None``
+  that was explicitly passed to the :class:`.Context` and a value that
+  wasn't present at all.
+* **Why raise an exception when you call str() on it ? Why not
+  just return a blank string?** - Mako tries to stick to the
+  Python philosophy of "explicit is better than implicit". In
+  this case, it's decided that the template author should be made
+  to specifically handle a missing value rather than
+  experiencing what may be a silent failure. Since ``UNDEFINED``
+  is a singleton object just like Python's ``True`` or ``False``,
+  you can use the ``is`` operator to check for it:
+
+  .. sourcecode:: mako
+
+        % if someval is UNDEFINED:
+            someval is: no value
+        % else:
+            someval is: ${someval}
+        % endif
+
+Another facet of the :class:`.Context` is that its dictionary of
+variables is **immutable**. Whatever is set when
+:meth:`~.Template.render` is called is what stays. Of course, since
+its Python, you can hack around this and change values in the
+context's internal dictionary, but this will probably will not
+work as well as you'd think. The reason for this is that Mako in
+many cases creates copies of the :class:`.Context` object, which
+get sent to various elements of the template and inheriting
+templates used in an execution. So changing the value in your
+local :class:`.Context` will not necessarily make that value
+available in other parts of the template's execution. Examples
+of where Mako creates copies of the :class:`.Context` include
+within top-level def calls from the main body of the template
+(the context is used to propagate locally assigned variables
+into the scope of defs; since in the template's body they appear
+as inlined functions, Mako tries to make them act that way), and
+within an inheritance chain (each template in an inheritance
+chain has a different notion of ``parent`` and ``next``, which
+are all stored in unique :class:`.Context` instances).
+
+* **So what if I want to set values that are global to everyone
+  within a template request?** - All you have to do is provide a
+  dictionary to your :class:`.Context` when the template first
+  runs, and everyone can just get/set variables from that. Lets
+  say its called ``attributes``.
+
+  Running the template looks like:
+
+  .. sourcecode:: python
+
+      output = template.render(attributes={})
+
+  Within a template, just reference the dictionary:
+
+  .. sourcecode:: mako
+
+      <%
+          attributes['foo'] = 'bar'
+      %>
+      'foo' attribute is: ${attributes['foo']}
+
+* **Why can't "attributes" be a built-in feature of the
+  Context?** - This is an area where Mako is trying to make as
+  few decisions about your application as it possibly can.
+  Perhaps you don't want your templates to use this technique of
+  assigning and sharing data, or perhaps you have a different
+  notion of the names and kinds of data structures that should
+  be passed around. Once again Mako would rather ask the user to
+  be explicit.
+
+Context Methods and Accessors
+-----------------------------
+
+Significant members of :class:`.Context` include:
+
+* ``context[key]`` / ``context.get(key, default=None)`` -
+  dictionary-like accessors for the context. Normally, any
+  variable you use in your template is automatically pulled from
+  the context if it isn't defined somewhere already. Use the
+  dictionary accessor and/or ``get`` method when you want a
+  variable that *is* already defined somewhere else, such as in
+  the local arguments sent to a ``%def`` call. If a key is not
+  present, like a dictionary it raises ``KeyError``.
+* ``keys()`` - all the names defined within this context.
+* ``kwargs`` - this returns a **copy** of the context's
+  dictionary of variables. This is useful when you want to
+  propagate the variables in the current context to a function
+  as keyword arguments, i.e.:
+
+  .. sourcecode:: mako
+
+        ${next.body(**context.kwargs)}
+
+* ``write(text)`` - write some text to the current output
+  stream.
+* ``lookup`` - returns the :class:`.TemplateLookup` instance that is
+  used for all file-lookups within the current execution (even
+  though individual :class:`.Template` instances can conceivably have
+  different instances of a :class:`.TemplateLookup`, only the
+  :class:`.TemplateLookup` of the originally-called :class:`.Template` gets
+  used in a particular execution).
+
+.. _loop_context:
+
+The Loop Context
+================
+
+Within ``% for`` blocks, the :ref:`reserved name<reserved_names>` ``loop``
+is available.  ``loop`` tracks the progress of
+the ``for`` loop and makes it easy to use the iteration state to control
+template behavior:
+
+.. sourcecode:: mako
+
+    <ul>
+    % for a in ("one", "two", "three"):
+        <li>Item ${loop.index}: ${a}</li>
+    % endfor
+    </ul>
+
+.. versionadded:: 0.7
+
+Iterations
+----------
+
+Regardless of the type of iterable you're looping over, ``loop`` always tracks
+the 0-indexed iteration count (available at ``loop.index``), its parity
+(through the ``loop.even`` and ``loop.odd`` bools), and ``loop.first``, a bool
+indicating whether the loop is on its first iteration.  If your iterable
+provides a ``__len__`` method, ``loop`` also provides access to
+a count of iterations remaining at ``loop.reverse_index`` and ``loop.last``,
+a bool indicating whether the loop is on its last iteration; accessing these
+without ``__len__`` will raise a ``TypeError``.
+
+Cycling
+-------
+
+Cycling is available regardless of whether the iterable you're using provides
+a ``__len__`` method.  Prior to Mako 0.7, you might have generated a simple
+zebra striped list using ``enumerate``:
+
+.. sourcecode:: mako
+
+    <ul>
+    % for i, item in enumerate(('spam', 'ham', 'eggs')):
+      <li class="${'odd' if i % 2 else 'even'}">${item}</li>
+    % endfor
+    </ul>
+
+With ``loop.cycle``, you get the same results with cleaner code and less prep work:
+
+.. sourcecode:: mako
+
+    <ul>
+    % for item in ('spam', 'ham', 'eggs'):
+      <li class="${loop.cycle('even', 'odd')}">${item}</li>
+    % endfor
+    </ul>
+
+Both approaches produce output like the following:
+
+.. sourcecode:: html
+
+    <ul>
+      <li class="even">spam</li>
+      <li class="odd">ham</li>
+      <li class="even">eggs</li>
+    </ul>
+
+Parent Loops
+------------
+
+Loop contexts can also be transparently nested, and the Mako runtime will do
+the right thing and manage the scope for you.  You can access the parent loop
+context through ``loop.parent``.
+
+This allows you to reach all the way back up through the loop stack by
+chaining ``parent`` attribute accesses, i.e. ``loop.parent.parent....`` as
+long as the stack depth isn't exceeded.  For example, you can use the parent
+loop to make a checkered table:
+
+.. sourcecode:: mako
+
+    <table>
+    % for consonant in 'pbj':
+      <tr>
+      % for vowel in 'iou':
+        <td class="${'black' if (loop.parent.even == loop.even) else 'red'}">
+          ${consonant + vowel}t
+        </td>
+      % endfor
+      </tr>
+    % endfor
+    </table>
+
+.. sourcecode:: html
+
+    <table>
+      <tr>
+        <td class="black">
+          pit
+        </td>
+        <td class="red">
+          pot
+        </td>
+        <td class="black">
+          put
+        </td>
+      </tr>
+      <tr>
+        <td class="red">
+          bit
+        </td>
+        <td class="black">
+          bot
+        </td>
+        <td class="red">
+          but
+        </td>
+      </tr>
+      <tr>
+        <td class="black">
+          jit
+        </td>
+        <td class="red">
+          jot
+        </td>
+        <td class="black">
+          jut
+        </td>
+      </tr>
+    </table>
+
+.. _migrating_loop:
+
+Migrating Legacy Templates that Use the Word "loop"
+---------------------------------------------------
+
+.. versionchanged:: 0.7
+   The ``loop`` name is now :ref:`reserved <reserved_names>` in Mako,
+   which means a template that refers to a variable named ``loop``
+   won't function correctly when used in Mako 0.7.
+
+To ease the transition for such systems, the feature can be disabled across the board for
+all templates, then re-enabled on a per-template basis for those templates which wish
+to make use of the new system.
+
+First, the ``enable_loop=False`` flag is passed to either the :class:`.TemplateLookup`
+or :class:`.Template` object in use:
+
+.. sourcecode:: python
+
+    lookup = TemplateLookup(directories=['/docs'], enable_loop=False)
+
+or:
+
+.. sourcecode:: python
+
+    template = Template("some template", enable_loop=False)
+
+An individual template can make usage of the feature when ``enable_loop`` is set to
+``False`` by switching it back on within the ``<%page>`` tag:
+
+.. sourcecode:: mako
+
+    <%page enable_loop="True"/>
+
+    % for i in collection:
+        ${i} ${loop.index}
+    % endfor
+
+Using the above scheme, it's safe to pass the name ``loop`` to the :meth:`.Template.render`
+method as well as to freely make usage of a variable named ``loop`` within a template, provided
+the ``<%page>`` tag doesn't override it.  New templates that want to use the ``loop`` context
+can then set up ``<%page enable_loop="True"/>`` to use the new feature without affecting
+old templates.
+
+All the Built-in Names
+======================
+
+A one-stop shop for all the names Mako defines. Most of these
+names are instances of :class:`.Namespace`, which are described
+in the next section, :ref:`namespaces_toplevel`. Also, most of
+these names other than ``context``, ``UNDEFINED``, and ``loop`` are
+also present *within* the :class:`.Context` itself.   The names
+``context``, ``loop`` and ``UNDEFINED`` themselves can't be passed
+to the context and can't be substituted -- see the section :ref:`reserved_names`.
+
+* ``context`` - this is the :class:`.Context` object, introduced
+  at :ref:`context`.
+* ``local`` - the namespace of the current template, described
+  in :ref:`namespaces_builtin`.
+* ``self`` - the namespace of the topmost template in an
+  inheritance chain (if any, otherwise the same as ``local``),
+  mostly described in :ref:`inheritance_toplevel`.
+* ``parent`` - the namespace of the parent template in an
+  inheritance chain (otherwise undefined); see
+  :ref:`inheritance_toplevel`.
+* ``next`` - the namespace of the next template in an
+  inheritance chain (otherwise undefined); see
+  :ref:`inheritance_toplevel`.
+* ``caller`` - a "mini" namespace created when using the
+  ``<%call>`` tag to define a "def call with content"; described
+  in :ref:`defs_with_content`.
+* ``loop`` - this provides access to :class:`.LoopContext` objects when
+  they are requested within ``% for`` loops, introduced at :ref:`loop_context`.
+* ``capture`` - a function that calls a given def and captures
+  its resulting content into a string, which is returned. Usage
+  is described in :ref:`filtering_toplevel`.
+* ``UNDEFINED`` - a global singleton that is applied to all
+  otherwise uninitialized template variables that were not
+  located within the :class:`.Context` when rendering began,
+  unless the :class:`.Template` flag ``strict_undefined``
+  is set to ``True``. ``UNDEFINED`` is
+  an instance of :class:`.Undefined`, and raises an
+  exception when its ``__str__()`` method is called.
+* ``pageargs`` - this is a dictionary which is present in a
+  template which does not define any ``**kwargs`` section in its
+  ``<%page>`` tag. All keyword arguments sent to the ``body()``
+  function of a template (when used via namespaces) go here by
+  default unless otherwise defined as a page argument. If this
+  makes no sense, it shouldn't; read the section
+  :ref:`namespaces_body`.
+
+.. _reserved_names:
+
+Reserved Names
+--------------
+
+Mako has a few names that are considered to be "reserved" and can't be used
+as variable names.
+
+.. versionchanged:: 0.7
+   Mako raises an error if these words are found passed to the template
+   as context arguments, whereas in previous versions they'd be silently
+   ignored or lead to other error messages.
+
+* ``context`` - see :ref:`context`.
+* ``UNDEFINED`` - see :ref:`context_vars`.
+* ``loop`` - see :ref:`loop_context`.  Note this can be disabled for legacy templates
+  via the ``enable_loop=False`` argument; see :ref:`migrating_loop`.
+
+API Reference
+=============
+
+.. autoclass:: mako.runtime.Context
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.runtime.LoopContext
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.runtime.Undefined
+    :show-inheritance:
+
diff --git a/lib3/Mako-0.7.3/doc/build/static/docs.css b/lib3/Mako-0.7.3/doc/build/static/docs.css
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/static/docs.css
@@ -0,0 +1,438 @@
+/* global */
+
+body {
+  background-color: #FDFBFC;
+  margin:38px;
+  color:#333333;
+}
+
+a {
+    font-weight:normal; 
+    text-decoration:none;
+}
+
+form {
+    display:inline;
+}
+
+/* hyperlinks */
+
+a:link, a:visited, a:active {
+    color:#0000FF;
+}
+a:hover {
+    color:#700000;
+    text-decoration:underline;
+}
+
+/* paragraph links after sections.
+   These aren't visible until hovering
+   over the <h> tag, then have a 
+   "reverse video" effect over the actual
+   link
+ */
+
+a.headerlink {
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+a.headerlink:hover {
+    background-color: #990000;
+    color: white;
+}
+
+
+/* Container setup */
+
+#docs-container {
+  max-width:1000px;
+}
+
+
+/* header/footer elements */
+
+#docs-header h1 {
+    font-size:20px;
+    color: #222222;
+    margin: 0;
+    padding: 0;
+}
+
+#docs-header {
+  font-family:Tahoma, Geneva,sans-serif;
+
+  font-size:.9em;
+
+}
+
+#docs-top-navigation,
+#docs-bottom-navigation {
+  font-family: Tahoma, Geneva, sans-serif;
+  background-color: #EEE;
+  border: solid 1px #CCC;
+  padding:10px;
+  font-size:.9em;
+}
+
+#docs-top-navigation {
+  margin:10px 0px 10px 0px;
+  line-height:1.2em;
+}
+
+.docs-navigation-links {
+  font-family:Tahoma, Geneva,sans-serif;
+}
+
+#docs-bottom-navigation {
+    float:right;
+    margin: 1em 0 1em 5px;
+}
+
+#docs-copyright {
+    font-size:.85em;
+    padding:5px 0px;
+}
+
+#docs-header h1,
+#docs-top-navigation h1,
+#docs-top-navigation h2 {
+  font-family:Tahoma,Geneva,sans-serif;
+  font-weight:normal;
+}
+
+#docs-top-navigation h2 {
+    margin:16px 4px 7px 5px;
+    font-size:2em;
+}
+
+#docs-search {
+    float:right;
+}
+
+#docs-top-page-control {
+  float:right;
+  width:350px;
+}
+
+#docs-top-page-control ul {
+  padding:0;
+  margin:0;
+}
+
+#docs-top-page-control li {
+    list-style-type:none;
+    padding:1px 8px;
+}
+
+
+#docs-container .version-num {
+    font-weight: bold;
+}
+
+
+/* content container, sidebar */
+
+#docs-body-container {
+  background-color:#EFEFEF;
+  border: solid 1px #CCC;
+
+}
+
+#docs-body,
+#docs-sidebar
+ {
+  /*font-family: helvetica, arial, sans-serif;
+  font-size:.9em;*/
+
+  font-family: Tahoma, Geneva, sans-serif;
+  /*font-size:.85em;*/
+  line-height:1.5em;
+
+}
+
+#docs-sidebar > ul {
+  font-size:.9em;
+}
+
+#docs-sidebar {
+  float:left;
+  width:212px;
+  padding: 10px 0 0 15px;
+  /*font-size:.85em;*/
+}
+
+#docs-sidebar h3, #docs-sidebar h4 {
+    background-color: #DDDDDD;
+    color: #222222;
+    font-family: Tahoma, Geneva,sans-serif;
+    font-size: 1.1em;
+    font-weight: normal;
+    margin: 10px 0 0 -15px;
+    padding: 5px 10px 5px 10px;
+    text-shadow: 1px 1px 0 white;
+    width:210px;
+}
+
+#docs-sidebar h3 a, #docs-sidebar h4 a {
+  color: #222222;
+}
+#docs-sidebar ul {
+  margin: 10px 10px 10px 0px;
+  padding: 0;
+  list-style: none outside none;
+}
+
+
+#docs-sidebar ul ul {
+    margin-bottom: 0;
+    margin-top: 0;
+    list-style: square outside none;
+    margin-left: 20px;
+}
+
+#docs-body {
+  background-color:#FFFFFF;
+  padding:1px 10px 10px 10px;
+}
+
+#docs-body.withsidebar {
+  margin: 0 0 0 230px;
+  border-left:3px solid #DFDFDF;
+}
+
+#docs-body h1,
+#docs-body h2,
+#docs-body h3,
+#docs-body h4 {
+  font-family:Tahoma, Geneva, sans-serif;
+}
+
+#docs-body h1 {
+  /* hide the <h1> for each content section. */
+  display:none;
+  font-size:1.8em;
+}
+
+#docs-body h2 {
+  font-size:1.6em;
+}
+
+#docs-body h3 {
+  font-size:1.4em;
+}
+
+/* SQL popup, code styles */
+
+.highlight {
+  background:none;
+}
+
+#docs-container pre {
+  font-size:1.2em;
+}
+
+#docs-container .pre {
+  font-size:1.1em;
+}
+
+#docs-container pre {
+  background-color: #f0f0f0;  
+  border: solid 1px #ccc;
+  box-shadow: 2px 2px 3px #DFDFDF;
+  padding:10px;
+  margin: 5px 0px 5px 0px;
+  overflow:auto;
+  line-height:1.3em;
+}
+
+.popup_sql, .show_sql
+{
+    background-color: #FBFBEE;
+    padding:5px 10px;
+    margin:10px -5px;
+    border:1px dashed;
+}
+
+/* the [SQL] links used to display SQL */
+#docs-container .sql_link
+{
+  font-weight:normal;
+  font-family: arial, sans-serif;
+  font-size:.9em;
+  text-transform: uppercase;
+  color:#990000;
+  border:1px solid;
+  padding:1px 2px 1px 2px;
+  margin:0px 10px 0px 15px;
+  float:right;
+  line-height:1.2em;
+}
+
+#docs-container a.sql_link, 
+#docs-container .sql_link
+{
+    text-decoration: none;
+    padding:1px 2px;
+}
+
+#docs-container a.sql_link:hover {
+    text-decoration: none;
+    color:#fff;
+    border:1px solid #900;
+    background-color: #900;
+}
+
+/* docutils-specific elements */
+
+th.field-name {
+    text-align:right;
+}
+
+div.note, div.warning, p.deprecated, div.topic  {
+    background-color:#EEFFEF;
+}
+
+
+div.admonition, div.topic, p.deprecated, p.versionadded, p.versionchanged {
+    border:1px solid #CCCCCC;
+    padding:5px 10px;
+    font-size:.9em;
+    box-shadow: 2px 2px 3px #DFDFDF;
+}
+
+div.warning .admonition-title {
+    color:#FF0000;
+}
+
+div.admonition .admonition-title, div.topic .topic-title {
+    font-weight:bold;
+}
+
+.viewcode-back, .viewcode-link {
+    float:right;
+}
+
+dl.function > dt,
+dl.attribute > dt,
+dl.classmethod > dt,
+dl.method > dt,
+dl.class > dt,
+dl.exception > dt
+{
+    background-color:#F0F0F0;
+    margin:25px -10px 10px 10px;
+    padding: 0px 10px;
+}
+
+p.versionadded span.versionmodified,
+p.versionchanged span.versionmodified,
+p.deprecated span.versionmodified {
+    background-color: #F0F0F0;
+    font-style: italic;
+}
+
+dt:target, span.highlight {
+    background-color:#FBE54E;
+}
+
+a.headerlink {
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+a.headerlink:hover {
+    background-color: #00f;
+    color: white;
+}
+
+.clearboth {
+    clear:both;
+}
+
+tt.descname {
+    background-color:transparent;
+    font-size:1.2em;
+    font-weight:bold;
+}
+
+tt.descclassname {
+    background-color:transparent;
+}
+
+tt {
+    background-color:#ECF0F3;
+    padding:0 1px;
+}
+
+/* syntax highlighting overrides */
+.k, .kn {color:#0908CE;}
+.o {color:#BF0005;}
+.go {color:#804049;}
+
+
+/* special "index page" sections 
+   with specific formatting
+*/
+
+div#sqlalchemy-documentation {
+  font-size:.95em;
+}
+div#sqlalchemy-documentation em {
+  font-style:normal;
+}
+div#sqlalchemy-documentation .rubric{
+  font-size:14px;
+  background-color:#EEFFEF;
+  padding:5px;
+  border:1px solid #BFBFBF;
+}
+div#sqlalchemy-documentation a, div#sqlalchemy-documentation li {
+  padding:5px 0px;
+}
+
+div#getting-started {
+  border-bottom:1px solid;
+}
+
+div#sqlalchemy-documentation div#sqlalchemy-orm {
+  float:left;
+  width:48%;
+}
+
+div#sqlalchemy-documentation div#sqlalchemy-core {
+  float:left;
+  width:48%;
+  margin:0;
+  padding-left:10px;
+  border-left:1px solid;
+}
+
+div#dialect-documentation {
+  border-top:1px solid;
+  /*clear:left;*/
+}
diff --git a/lib3/Mako-0.7.3/doc/build/static/makoLogo.png b/lib3/Mako-0.7.3/doc/build/static/makoLogo.png
new file mode 100644
index 0000000000000000000000000000000000000000..c43c087eb48ebfc2223b76cf3df2fa7868c2a72b
GIT binary patch
[stripped]
diff --git a/lib3/Mako-0.7.3/doc/build/static/site.css b/lib3/Mako-0.7.3/doc/build/static/site.css
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/static/site.css
@@ -0,0 +1,86 @@
+body {
+    font-family: Tahoma, Geneva, sans-serif;
+    line-height:1.4em;
+    margin:15px;
+    background-color:#FFFFFF;
+}
+img {border:none;}
+a { text-decoration: none;}
+a:visited  { color: #2929ff;}
+a:hover { color: #0000ff;}
+
+#wrap {
+    margin:0 auto;
+    max-width:1024px;
+    min-width:480px;
+    position:relative;
+
+}
+h1 {
+    font-size:1.6em;
+    font-weight:bold;
+}
+
+h2 {
+    font-size:1.1em;
+    font-weight:bold;
+    margin:10px 0px 10px 0px;
+}
+
+.clearfix{
+    clear:both;
+}
+
+.red {
+	font-weight:bold;
+	color:#FF0000;
+}
+.rightbar {
+    float:right;
+}
+.slogan {
+    margin-top:10px;
+}
+#gittip_nav {
+    float:right;
+    margin:10px 0px 0px 0px;
+}
+
+.toolbar {
+    margin-top:20px;
+}
+.copyright {
+    font-size:.8em;
+    text-align:center;
+    color:909090;
+}
+.pylogo {
+	text-align:right;
+	float:right;
+}
+.code {
+    font-family:monospace;
+}
+
+li {
+    margin:1px 0px 1px 0px;
+}
+
+.speedchart td {
+    font-size:small;
+}
+
+pre.codesample {
+    margin: 1.5em;
+    padding: .5em;
+    font-size: .95em;
+    line-height:1em;
+    background-color: #eee;
+    border: 1px solid #ccc;
+    width:450px;
+    overflow:auto;
+}
+
+#speedchart {
+    margin:5px 10px 5px 10px;
+}
diff --git a/lib3/Mako-0.7.3/doc/build/syntax.rst b/lib3/Mako-0.7.3/doc/build/syntax.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/syntax.rst
@@ -0,0 +1,469 @@
+.. _syntax_toplevel:
+
+======
+Syntax
+======
+
+A Mako template is parsed from a text stream containing any kind
+of content, XML, HTML, email text, etc. The template can further
+contain Mako-specific directives which represent variable and/or
+expression substitutions, control structures (i.e. conditionals
+and loops), server-side comments, full blocks of Python code, as
+well as various tags that offer additional functionality. All of
+these constructs compile into real Python code. This means that
+you can leverage the full power of Python in almost every aspect
+of a Mako template.
+
+Expression Substitution
+=======================
+
+The simplest expression is just a variable substitution. The
+syntax for this is the ``${}`` construct, which is inspired by
+Perl, Genshi, JSP EL, and others:
+
+.. sourcecode:: mako
+
+    this is x: ${x}
+
+Above, the string representation of ``x`` is applied to the
+template's output stream. If you're wondering where ``x`` comes
+from, it's usually from the :class:`.Context` supplied to the
+template's rendering function. If ``x`` was not supplied to the
+template and was not otherwise assigned locally, it evaluates to
+a special value ``UNDEFINED``. More on that later.
+
+The contents within the ``${}`` tag are evaluated by Python
+directly, so full expressions are OK:
+
+.. sourcecode:: mako
+
+    pythagorean theorem:  ${pow(x,2) + pow(y,2)}
+
+The results of the expression are evaluated into a string result
+in all cases before being rendered to the output stream, such as
+the above example where the expression produces a numeric
+result.
+
+Expression Escaping
+===================
+
+Mako includes a number of built-in escaping mechanisms,
+including HTML, URI and XML escaping, as well as a "trim"
+function. These escapes can be added to an expression
+substitution using the ``|`` operator:
+
+.. sourcecode:: mako
+
+    ${"this is some text" | u}
+
+The above expression applies URL escaping to the expression, and
+produces ``this+is+some+text``. The ``u`` name indicates URL
+escaping, whereas ``h`` represents HTML escaping, ``x``
+represents XML escaping, and ``trim`` applies a trim function.
+
+Read more about built-in filtering functions, including how to
+make your own filter functions, in :ref:`filtering_toplevel`.
+
+Control Structures
+==================
+
+A control structure refers to all those things that control the
+flow of a program -- conditionals (i.e. ``if``/``else``), loops (like
+``while`` and ``for``), as well as things like ``try``/``except``. In Mako,
+control structures are written using the ``%`` marker followed
+by a regular Python control expression, and are "closed" by
+using another ``%`` marker with the tag "``end<name>``", where
+"``<name>``" is the keyword of the expression:
+
+.. sourcecode:: mako
+
+    % if x==5:
+        this is some output
+    % endif
+
+The ``%`` can appear anywhere on the line as long as no text
+precedes it; indentation is not significant. The full range of
+Python "colon" expressions are allowed here, including
+``if``/``elif``/``else``, ``while``, ``for``, and even ``def``, although
+Mako has a built-in tag for defs which is more full-featured.
+
+.. sourcecode:: mako
+
+    % for a in ['one', 'two', 'three', 'four', 'five']:
+        % if a[0] == 't':
+        its two or three
+        % elif a[0] == 'f':
+        four/five
+        % else:
+        one
+        % endif
+    % endfor
+
+The ``%`` sign can also be "escaped", if you actually want to
+emit a percent sign as the first non whitespace character on a
+line, by escaping it as in ``%%``:
+
+.. sourcecode:: mako
+
+    %% some text
+
+        %% some more text
+
+The Loop Context
+----------------
+
+The **loop context** provides additional information about a loop
+while inside of a ``% for`` structure:
+
+.. sourcecode:: mako
+
+    <ul>
+    % for a in ("one", "two", "three"):
+        <li>Item ${loop.index}: ${a}</li>
+    % endfor
+    </ul>
+
+See :ref:`loop_context` for more information on this feature.
+
+.. versionadded:: 0.7
+
+Comments
+========
+
+Comments come in two varieties. The single line comment uses
+``##`` as the first non-space characters on a line:
+
+.. sourcecode:: mako
+
+    ## this is a comment.
+    ...text ...
+
+A multiline version exists using ``<%doc> ...text... </%doc>``:
+
+.. sourcecode:: mako
+
+    <%doc>
+        these are comments
+        more comments
+    </%doc>
+
+Newline Filters
+===============
+
+The backslash ("``\``") character, placed at the end of any
+line, will consume the newline character before continuing to
+the next line:
+
+.. sourcecode:: mako
+
+    here is a line that goes onto \
+    another line.
+
+The above text evaluates to:
+
+.. sourcecode:: text
+
+    here is a line that goes onto another line.
+
+Python Blocks
+=============
+
+Any arbitrary block of python can be dropped in using the ``<%
+%>`` tags:
+
+.. sourcecode:: mako
+
+    this is a template
+    <%
+        x = db.get_resource('foo')
+        y = [z.element for z in x if x.frobnizzle==5]
+    %>
+    % for elem in y:
+        element: ${elem}
+    % endfor
+
+Within ``<% %>``, you're writing a regular block of Python code.
+While the code can appear with an arbitrary level of preceding
+whitespace, it has to be consistently formatted with itself.
+Mako's compiler will adjust the block of Python to be consistent
+with the surrounding generated Python code.
+
+Module-level Blocks
+===================
+
+A variant on ``<% %>`` is the module-level code block, denoted
+by ``<%! %>``. Code within these tags is executed at the module
+level of the template, and not within the rendering function of
+the template. Therefore, this code does not have access to the
+template's context and is only executed when the template is
+loaded into memory (which can be only once per application, or
+more, depending on the runtime environment). Use the ``<%! %>``
+tags to declare your template's imports, as well as any
+pure-Python functions you might want to declare:
+
+.. sourcecode:: mako
+
+    <%!
+        import mylib
+        import re
+
+        def filter(text):
+            return re.sub(r'^@', '', text)
+    %>
+
+Any number of ``<%! %>`` blocks can be declared anywhere in a
+template; they will be rendered in the resulting module 
+in a single contiguous block above all render callables,
+in the order in which they appear in the source template.
+
+Tags
+====
+
+The rest of what Mako offers takes place in the form of tags.
+All tags use the same syntax, which is similar to an XML tag
+except that the first character of the tag name is a ``%``
+character. The tag is closed either by a contained slash
+character, or an explicit closing tag:
+
+.. sourcecode:: mako
+
+    <%include file="foo.txt"/>
+
+    <%def name="foo" buffered="True">
+        this is a def
+    </%def>
+
+All tags have a set of attributes which are defined for each
+tag. Some of these attributes are required. Also, many
+attributes support **evaluation**, meaning you can embed an
+expression (using ``${}``) inside the attribute text:
+
+.. sourcecode:: mako
+
+    <%include file="/foo/bar/${myfile}.txt"/>
+
+Whether or not an attribute accepts runtime evaluation depends
+on the type of tag and how that tag is compiled into the
+template. The best way to find out if you can stick an
+expression in is to try it! The lexer will tell you if it's not
+valid.
+
+Heres a quick summary of all the tags:
+
+``<%page>``
+-----------
+
+This tag defines general characteristics of the template,
+including caching arguments, and optional lists of arguments
+which the template expects when invoked.
+
+.. sourcecode:: mako
+
+    <%page args="x, y, z='default'"/>
+
+Or a page tag that defines caching characteristics:
+
+.. sourcecode:: mako
+
+    <%page cached="True" cache_type="memory"/>
+
+Currently, only one ``<%page>`` tag gets used per template, the
+rest get ignored. While this will be improved in a future
+release, for now make sure you have only one ``<%page>`` tag
+defined in your template, else you may not get the results you
+want. The details of what ``<%page>`` is used for are described
+further in :ref:`namespaces_body` as well as :ref:`caching_toplevel`.
+
+``<%include>``
+--------------
+
+A tag that is familiar from other template languages, ``%include``
+is a regular joe that just accepts a file argument and calls in
+the rendered result of that file:
+
+.. sourcecode:: mako
+
+    <%include file="header.html"/>
+
+        hello world
+
+    <%include file="footer.html"/>
+
+Include also accepts arguments which are available as ``<%page>`` arguments in the receiving template:
+
+.. sourcecode:: mako
+
+    <%include file="toolbar.html" args="current_section='members', username='ed'"/>
+
+``<%def>``
+----------
+
+The ``%def`` tag defines a Python function which contains a set
+of content, that can be called at some other point in the
+template. The basic idea is simple:
+
+.. sourcecode:: mako
+
+    <%def name="myfunc(x)">
+        this is myfunc, x is ${x}
+    </%def>
+
+    ${myfunc(7)}
+
+The ``%def`` tag is a lot more powerful than a plain Python ``def``, as
+the Mako compiler provides many extra services with ``%def`` that
+you wouldn't normally have, such as the ability to export defs
+as template "methods", automatic propagation of the current
+:class:`.Context`, buffering/filtering/caching flags, and def calls
+with content, which enable packages of defs to be sent as
+arguments to other def calls (not as hard as it sounds). Get the
+full deal on what ``%def`` can do in :ref:`defs_toplevel`.
+
+``<%block>``
+------------
+
+``%block`` is a tag that is close to a ``%def``,
+except executes itself immediately in its base-most scope,
+and can also be anonymous (i.e. with no name):
+
+.. sourcecode:: mako
+
+    <%block filter="h">
+        some <html> stuff.
+    </%block>
+
+Inspired by Jinja2 blocks, named blocks offer a syntactically pleasing way
+to do inheritance:
+
+.. sourcecode:: mako
+
+    <html>
+        <body>
+        <%block name="header">
+            <h2><%block name="title"/></h2>
+        </%block>
+        ${self.body()}
+        </body>
+    </html>
+
+Blocks are introduced in :ref:`blocks` and further described in :ref:`inheritance_toplevel`.
+
+.. versionadded:: 0.4.1
+
+``<%namespace>``
+----------------
+
+``%namespace`` is Mako's equivalent of Python's ``import``
+statement. It allows access to all the rendering functions and
+metadata of other template files, plain Python modules, as well
+as locally defined "packages" of functions.
+
+.. sourcecode:: mako
+
+    <%namespace file="functions.html" import="*"/>
+
+The underlying object generated by ``%namespace``, an instance of
+:class:`.mako.runtime.Namespace`, is a central construct used in
+templates to reference template-specific information such as the
+current URI, inheritance structures, and other things that are
+not as hard as they sound right here. Namespaces are described
+in :ref:`namespaces_toplevel`.
+
+``<%inherit>``
+--------------
+
+Inherit allows templates to arrange themselves in **inheritance
+chains**. This is a concept familiar in many other template
+languages.
+
+.. sourcecode:: mako
+
+    <%inherit file="base.html"/>
+
+When using the ``%inherit`` tag, control is passed to the topmost
+inherited template first, which then decides how to handle
+calling areas of content from its inheriting templates. Mako
+offers a lot of flexibility in this area, including dynamic
+inheritance, content wrapping, and polymorphic method calls.
+Check it out in :ref:`inheritance_toplevel`.
+
+``<%``\ nsname\ ``:``\ defname\ ``>``
+-------------------------------------
+
+Any user-defined "tag" can be created against
+a namespace by using a tag with a name of the form
+``<%<namespacename>:<defname>>``. The closed and open formats of such a
+tag are equivalent to an inline expression and the ``<%call>``
+tag, respectively.
+
+.. sourcecode:: mako
+
+    <%mynamespace:somedef param="some value">
+        this is the body
+    </%mynamespace:somedef>
+
+To create custom tags which accept a body, see
+:ref:`defs_with_content`.
+
+.. versionadded:: 0.2.3
+
+``<%call>``
+-----------
+
+The call tag is the "classic" form of a user-defined tag, and is
+roughly equivalent to the ``<%namespacename:defname>`` syntax
+described above. This tag is also described in :ref:`defs_with_content`.
+
+``<%doc>``
+----------
+
+The ``%doc`` tag handles multiline comments:
+
+.. sourcecode:: mako
+
+    <%doc>
+        these are comments
+        more comments
+    </%doc>
+
+Also the ``##`` symbol as the first non-space characters on a line can be used for single line comments.
+
+``<%text>``
+-----------
+
+This tag suspends the Mako lexer's normal parsing of Mako
+template directives, and returns its entire body contents as
+plain text. It is used pretty much to write documentation about
+Mako:
+
+.. sourcecode:: mako
+
+    <%text filter="h">
+        heres some fake mako ${syntax}
+        <%def name="x()">${x}</%def>
+    </%text>
+
+Returning Early from a Template
+===============================
+
+Sometimes you want to stop processing a template or ``<%def>``
+method in the middle and just use the text you've accumulated so
+far. You can use a ``return`` statement inside a Python
+block to do that.
+
+.. sourcecode:: mako
+
+    % if not len(records):
+        No records found.
+        <% return %>
+    % endif
+
+Or perhaps:
+
+.. sourcecode:: mako
+
+    <%
+        if not len(records):
+            return
+    %>
+
diff --git a/lib3/Mako-0.7.3/doc/build/templates/base.mako b/lib3/Mako-0.7.3/doc/build/templates/base.mako
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/templates/base.mako
@@ -0,0 +1,60 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title><%block name="head_title">Mako Templates for Python</%block></title>
+<%block name="headers">
+</%block>
+<link rel="stylesheet" href="${pathto('_static/site.css', 1)}"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+    % if toolbar:
+    <div id="gittip_nav">
+    <iframe style="border: 0; margin: 0; padding: 0;"
+    src="https://www.gittip.com/zzzeek/widget.html"
+    width="48pt" height="20pt"></iframe>
+    </div>
+    % endif
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+    % if toolbar:
+    <div class="toolbar">
+    <a href="${site_base}/">Home</a>
+      |  
+    <a href="${site_base}/trac">Trac</a>
+      |  
+    <a href="${site_base}/community.html">Community</a>
+      |  
+    <a href="${pathto('index')}">Documentation</a>
+      |  
+    <a href="${site_base}/download.html">Download</a>
+    </div>
+    % endif
+
+    </div>
+
+    <a href="${site_base}/"><img src="${pathto('_static/makoLogo.png', 1)}" /></a>
+
+    <hr/>
+
+    ${next.body()}
+<div class="clearfix">
+<%block name="footer">
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+</%block>
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/build/templates/genindex.mako b/lib3/Mako-0.7.3/doc/build/templates/genindex.mako
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/templates/genindex.mako
@@ -0,0 +1,77 @@
+<%inherit file="${context['layout']}"/>
+
+<%block name="show_title" filter="util.striptags">
+    ${_('Index')}
+</%block>
+
+   <h1 id="index">${_('Index')}</h1>
+
+   % for i, (key, dummy) in enumerate(genindexentries):
+    ${i != 0 and '| ' or ''}<a href="#${key}"><strong>${key}</strong></a>
+   % endfor
+
+   <hr />
+
+   % for i, (key, entries) in enumerate(genindexentries):
+<h2 id="${key}">${key}</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    <%
+        breakat = genindexcounts[i] // 2
+        numcols = 1
+        numitems = 0
+    %>
+% for entryname, (links, subitems) in entries:
+
+<dt>
+    % if links:
+        <a href="${links[0][1]}">${entryname|h}</a>
+        % for unknown, link in links[1:]:
+            , <a href="${link}">[${i}]</a>
+        % endfor
+    % else:
+        ${entryname|h}
+    % endif
+</dt>
+
+    % if subitems:
+    <dd><dl>
+      % for subentryname, subentrylinks in subitems:
+      <dt><a href="${subentrylinks[0][1]}">${subentryname|h}</a>
+              % for j, (unknown, link) in enumerate(subentrylinks[1:]):
+                  <a href="${link}">[${j}]</a>
+              % endfor
+      </dt>
+      % endfor
+    </dl></dd>
+    % endif
+
+  <%
+    numitems = numitems + 1 + len(subitems)
+  %>
+  % if numcols <2 and numitems > breakat:
+     <%
+        numcols = numcols + 1
+     %>
+        </dl></td><td width="33%" valign="top"><dl>
+  % endif
+
+% endfor
+<dt></dt></dl>
+</td></tr></table>
+% endfor
+
+<%def name="sidebarrel()">
+% if split_index:
+   <h4>${_('Index')}</h4>
+   <p>
+   % for i, (key, dummy) in enumerate(genindexentries):
+       ${i > 0 and '| ' or ''}
+       <a href="${pathto('genindex-' + key)}"><strong>${key}</strong></a>
+   % endfor
+   </p>
+
+   <p><a href="${pathto('genindex-all')}"><strong>${_('Full index on one page')}</strong></a></p>
+% endif
+   ${parent.sidebarrel()}
+</%def>
diff --git a/lib3/Mako-0.7.3/doc/build/templates/layout.mako b/lib3/Mako-0.7.3/doc/build/templates/layout.mako
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/templates/layout.mako
@@ -0,0 +1,199 @@
+## coding: utf-8
+<%!
+    local_script_files = []
+%>
+<%doc>
+    Structural elements are all prefixed with "docs-"
+    to prevent conflicts when the structure is integrated into the 
+    main site.
+    
+    docs-container ->
+        docs-header ->
+            docs-search
+            docs-version-header
+        docs-top-navigation
+            docs-top-page-control
+            docs-navigation-banner
+        docs-body-container ->
+            docs-sidebar
+            docs-body
+        docs-bottom-navigation
+            docs-copyright
+</%doc>
+
+<%inherit file="base.mako"/>
+
+<%
+withsidebar = bool(toc) and current_page_name != 'index'
+%>
+
+<%block name="head_title">
+    % if current_page_name != 'index':
+    ${capture(self.show_title) | util.striptags} — 
+    % endif
+    ${docstitle|h}
+</%block>
+
+
+<div id="docs-container">
+
+<%block name="headers">
+    <link rel="stylesheet" href="${pathto('_static/pygments.css', 1)}" type="text/css" />
+    <link rel="stylesheet" href="${pathto('_static/docs.css', 1)}" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '${pathto("", 1)}',
+          VERSION:     '${release|h}',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '${file_suffix}'
+      };
+    </script>
+    % for scriptfile in script_files + self.attr.local_script_files:
+        <script type="text/javascript" src="${pathto(scriptfile, 1)}"></script>
+    % endfor
+    % if hasdoc('about'):
+        <link rel="author" title="${_('About these documents')}" href="${pathto('about')}" />
+    % endif
+    <link rel="index" title="${_('Index')}" href="${pathto('genindex')}" />
+    <link rel="search" title="${_('Search')}" href="${pathto('search')}" />
+    % if hasdoc('copyright'):
+        <link rel="copyright" title="${_('Copyright')}" href="${pathto('copyright')}" />
+    % endif
+    <link rel="top" title="${docstitle|h}" href="${pathto('index')}" />
+    % if parents:
+        <link rel="up" title="${parents[-1]['title']|util.striptags}" href="${parents[-1]['link']|h}" />
+    % endif
+    % if nexttopic:
+        <link rel="next" title="${nexttopic['title']|util.striptags}" href="${nexttopic['link']|h}" />
+    % endif
+    % if prevtopic:
+        <link rel="prev" title="${prevtopic['title']|util.striptags}" href="${prevtopic['link']|h}" />
+    % endif
+</%block>
+
+<div id="docs-header">
+    <h1>${docstitle|h}</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="${pathto('search')}" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="${_('Search')}" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">${release}</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+        % if prevtopic:
+            <li>Prev:
+            <a href="${prevtopic['link']|h}" title="${_('previous chapter')}">${prevtopic['title']}</a>
+            </li>
+        % endif
+        % if nexttopic:
+            <li>Next:
+            <a href="${nexttopic['link']|h}" title="${_('next chapter')}">${nexttopic['title']}</a>
+            </li>
+        % endif
+
+        <li>
+            <a href="${pathto('index')}">Table of Contents</a> |
+            <a href="${pathto('genindex')}">Index</a>
+            % if sourcename:
+            | <a href="${pathto('_sources/' + sourcename, True)|h}">${_('view source')}
+            % endif
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="${pathto('index')}">${docstitle|h}</a>
+        % if parents:
+            % for parent in parents:
+                » <a href="${parent['link']|h}" title="${parent['title']}">${parent['title']}</a>
+            % endfor
+        % endif
+        % if current_page_name != 'index':
+        » ${self.show_title()} 
+        % endif
+
+        <h2>
+            <%block name="show_title">
+                ${title}
+            </%block>
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+% if withsidebar:
+    <div id="docs-sidebar">
+    <h3><a href="${pathto('index')}">Table of Contents</a></h3>
+    ${toc}
+
+    % if prevtopic:
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="${prevtopic['link']|h}" title="${_('previous chapter')}">${prevtopic['title']}</a>
+    </p>
+    % endif
+    % if nexttopic:
+    <h4>Next Topic</h4>
+    <p>
+    <a href="${nexttopic['link']|h}" title="${_('next chapter')}">${nexttopic['title']}</a>
+    </p>
+    % endif
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="${pathto('search')}" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="${_('Search')}" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+% endif
+
+    <div id="docs-body" class="${'withsidebar' if withsidebar else ''}" >
+        ${next.body()}
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+    % if prevtopic:
+        Previous:
+        <a href="${prevtopic['link']|h}" title="${_('previous chapter')}">${prevtopic['title']}</a>
+    % endif
+    % if nexttopic:
+        Next:
+        <a href="${nexttopic['link']|h}" title="${_('next chapter')}">${nexttopic['title']}</a>
+    % endif
+
+    <div id="docs-copyright">
+    % if hasdoc('copyright'):
+        © <a href="${pathto('copyright')}">Copyright</a> ${copyright|h}.
+    % else:
+        © Copyright ${copyright|h}.
+    % endif
+    % if show_sphinx:
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> ${sphinx_version|h} 
+        with Mako templates.
+    % endif
+    </div>
+</div>
+
+</div>
diff --git a/lib3/Mako-0.7.3/doc/build/templates/page.mako b/lib3/Mako-0.7.3/doc/build/templates/page.mako
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/templates/page.mako
@@ -0,0 +1,2 @@
+<%inherit file="${context['layout']}"/>
+${body| util.strip_toplevel_anchors}
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/doc/build/templates/rtd_layout.mako b/lib3/Mako-0.7.3/doc/build/templates/rtd_layout.mako
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/templates/rtd_layout.mako
@@ -0,0 +1,174 @@
+<!-- readthedocs add-in template, ported from their jinja source -->
+
+<%inherit file="/layout.mako"/>
+
+<%
+    newscript = []
+    # strip out script files that RTD wants to provide
+    for script in script_files:
+        for token in ("jquery.js", "underscore.js", "doctools.js"):
+            if token in script:
+                break
+        else:
+            newscript.append(script)
+    script_files[:] = newscript
+%>
+
+<%block name="headers">
+    ${parent.headers()}
+<!-- RTD <head> -->
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
+<script type="text/javascript" src="${MEDIA_URL}javascript/underscore.js"></script>
+<script type="text/javascript" src="${MEDIA_URL}javascript/doctools.js"></script>
+<script type="text/javascript" src="${MEDIA_URL}javascript/searchtools.js"></script>
+##{% if using_theme %}
+##  <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
+##{% endif %}
+  <script type="text/javascript">
+    var doc_version = "${current_version}";
+    var doc_slug = "${slug}";
+  </script>
+  <script type="text/javascript" src="${MEDIA_URL}javascript/rtd.js"></script>
+<!-- end RTD <head> -->
+</%block>
+
+${next.body()}
+
+<%block name="footer">
+    ${parent.footer()}
+ <!-- End original user content -->
+## Keep this here, so that the RTD logo doesn't stomp on the bottom of the theme.
+<br>
+<br>
+<br>
+
+<style type="text/css">
+  .badge {
+    position: fixed;
+    display: block;
+    bottom: 5px;
+    height: 40px;
+    text-indent: -9999em;
+    border-radius: 3px;
+    -moz-border-radius: 3px;
+    -webkit-border-radius: 3px;
+    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;
+    -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;
+    -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 1px 0 rgba(255, 255, 255, 0.2) inset;
+  }
+  #version_menu {
+    position: fixed;
+    display: none;
+    bottom: 11px;
+    right: 166px;
+    list-style-type: none;
+    margin: 0;
+  }
+  .footer_popout:hover #version_menu {
+    display: block;
+  }
+  #version_menu li {
+    display: block;
+    float: right;
+  }
+  #version_menu li a {
+    display: block;
+    padding: 6px 10px 4px 10px;
+    margin: 7px 7px 0 0;
+    font-weight: bold;
+    font-size: 14px;
+    height: 20px;
+    line-height: 17px;
+    text-decoration: none;
+    color: #fff;
+    background: #8ca1af url(../images/gradient-light.png) bottom left repeat-x;
+    border-radius: 3px;
+    -moz-border-radius: 3px;
+    -webkit-border-radius: 3px;
+    box-shadow: 0 1px 1px #465158;
+    -moz-box-shadow: 0 1px 1px #465158;
+    -webkit-box-shadow: 0 1px 1px #465158;
+    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
+  }
+  #version_menu li a:hover {
+    text-decoration: none;
+    background-color: #697983;
+    box-shadow: 0 1px 0px #465158;
+    -moz-box-shadow: 0 1px 0px #465158;
+    -webkit-box-shadow: 0 1px 0px #465158;
+  }
+  .badge.rtd {
+    background: #257597 url(http://media.readthedocs.org/images/badge-rtd.png) top left no-repeat;
+    border: 1px solid #282E32;
+    width: 160px;
+    right: 5px;
+  }
+  .badge.revsys { background: #465158 url(http://media.readthedocs.org/images/badge-revsys.png) top left no-repeat;
+    border: 1px solid #1C5871;
+    width: 290px;
+    right: 173px;
+  }
+  .badge.revsys-inline-sponsored {
+    position: inherit;
+    margin-left: auto;
+    margin-right: 175px;
+    margin-bottom: 5px;
+    background: #465158 url(http://media.readthedocs.org/images/badge-revsys.png) top left no-repeat;
+    border: 1px solid #1C5871;
+    width: 290px;
+    right: 173px;
+  }
+  .badge.revsys-inline {
+    position: inherit;
+    margin-left: auto;
+    margin-right: 175px;
+    margin-bottom: 5px;
+    background: #465158 url(http://media.readthedocs.org/images/badge-revsys-sm.png) top left no-repeat;
+    border: 1px solid #1C5871;
+    width: 205px;
+    right: 173px;
+  }
+
+</style>
+<div class="rtd_doc_footer">
+  <div class="footer_popout">
+    <a href="http://readthedocs.org/projects/${slug}/?fromdocs=${slug}" class="badge rtd">Brought to you by Read the Docs</a>
+    <ul id="version_menu">
+      ## note that rtd.js blows this away, probably checks if the links
+      ## are good or something like that (in which case why are they in the 'versions' 
+      ## collection...)
+      % for _slug, url in versions:
+        <li><a href="http://readthedocs.org${url}">${_slug}</a></li>
+      % endfor
+    </ul>
+  </div>
+</div>
+<!-- RTD Analytics Code -->
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-17997319-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+
+% if analytics_code:
+<!-- User Analytics Code -->
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', '${analytics_code}']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+% endif
+
+</%block>
diff --git a/lib3/Mako-0.7.3/doc/build/templates/search.mako b/lib3/Mako-0.7.3/doc/build/templates/search.mako
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/templates/search.mako
@@ -0,0 +1,25 @@
+<%inherit file="${context['layout']}"/>
+
+<%!
+    local_script_files = ['_static/searchtools.js']
+%>
+
+<%block name="show_title" filter="util.striptags">
+    ${_('Search')}
+</%block>
+
+<div id="searchform">
+<h3>Enter Search Terms:</h3>
+<form class="search" action="${pathto('search')}" method="get">
+  <input type="text" name="q" size="18" /> <input type="submit" value="${_('Search')}" />
+  <input type="hidden" name="check_keywords" value="yes" />
+  <input type="hidden" name="area" value="default" />
+</form>
+</div>
+
+<div id="search-results"></div>
+
+<%block name="footer">
+    ${parent.footer()}
+    <script type="text/javascript" src="searchindex.js"></script>
+</%block>
diff --git a/lib3/Mako-0.7.3/doc/build/unicode.rst b/lib3/Mako-0.7.3/doc/build/unicode.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/unicode.rst
@@ -0,0 +1,345 @@
+.. _unicode_toplevel:
+
+===================
+The Unicode Chapter
+===================
+
+The Python language supports two ways of representing what we
+know as "strings", i.e. series of characters. In Python 2, the
+two types are ``string`` and ``unicode``, and in Python 3 they are
+``bytes`` and ``string``. A key aspect of the Python 2 ``string`` and
+Python 3 ``bytes`` types are that they contain no information
+regarding what **encoding** the data is stored in. For this
+reason they were commonly referred to as **byte strings** on
+Python 2, and Python 3 makes this name more explicit. The
+origins of this come from Python's background of being developed
+before the Unicode standard was even available, back when
+strings were C-style strings and were just that, a series of
+bytes. Strings that had only values below 128 just happened to
+be **ASCII** strings and were printable on the console, whereas
+strings with values above 128 would produce all kinds of
+graphical characters and bells.
+
+Contrast the "byte-string" type with the "unicode/string" type.
+Objects of this latter type are created whenever you say something like
+``u"hello world"`` (or in Python 3, just ``"hello world"``). In this
+case, Python represents each character in the string internally
+using multiple bytes per character (something similar to
+UTF-16). What's important is that when using the
+``unicode``/``string`` type to store strings, Python knows the
+data's encoding; it's in its own internal format. Whereas when
+using the ``string``/``bytes`` type, it does not.
+
+When Python 2 attempts to treat a byte-string as a string, which
+means it's attempting to compare/parse its characters, to coerce
+it into another encoding, or to decode it to a unicode object,
+it has to guess what the encoding is. In this case, it will
+pretty much always guess the encoding as ``ascii``... and if the
+byte-string contains bytes above value 128, you'll get an error.
+Python 3 eliminates much of this confusion by just raising an
+error unconditionally if a byte-string is used in a
+character-aware context.
+
+There is one operation that Python *can* do with a non-ASCII
+byte-string, and it's a great source of confusion: it can dump the
+byte-string straight out to a stream or a file, with nary a care
+what the encoding is. To Python, this is pretty much like
+dumping any other kind of binary data (like an image) to a
+stream somewhere. In Python 2, it is common to see programs that
+embed all kinds of international characters and encodings into
+plain byte-strings (i.e. using ``"hello world"`` style literals)
+can fly right through their run, sending reams of strings out to
+wherever they are going, and the programmer, seeing the same
+output as was expressed in the input, is now under the illusion
+that his or her program is Unicode-compliant. In fact, their
+program has no unicode awareness whatsoever, and similarly has
+no ability to interact with libraries that *are* unicode aware.
+Python 3 makes this much less likely by defaulting to unicode as
+the storage format for strings.
+
+The "pass through encoded data" scheme is what template
+languages like Cheetah and earlier versions of Myghty do by
+default. Mako as of version 0.2 also supports this mode of
+operation when using Python 2, using the ``disable_unicode=True``
+flag. However, when using Mako in its default mode of
+unicode-aware, it requires explicitness when dealing with
+non-ASCII encodings. Additionally, if you ever need to handle
+unicode strings and other kinds of encoding conversions more
+intelligently, the usage of raw byte-strings quickly becomes a
+nightmare, since you are sending the Python interpreter
+collections of bytes for which it can make no intelligent
+decisions with regards to encoding. In Python 3 Mako only allows
+usage of native, unicode strings.
+
+In normal Mako operation, all parsed template constructs and
+output streams are handled internally as Python ``unicode``
+objects. It's only at the point of :meth:`~.Template.render` that this unicode
+stream may be rendered into whatever the desired output encoding
+is. The implication here is that the template developer must
+:ensure that :ref:`the encoding of all non-ASCII templates is explicit
+<set_template_file_encoding>` (still required in Python 3),
+that :ref:`all non-ASCII-encoded expressions are in one way or another
+converted to unicode <handling_non_ascii_expressions>`
+(not much of a burden in Python 3), and that :ref:`the output stream of the
+template is handled as a unicode stream being encoded to some
+encoding <defining_output_encoding>` (still required in Python 3).
+
+.. _set_template_file_encoding:
+
+Specifying the Encoding of a Template File
+==========================================
+
+This is the most basic encoding-related setting, and it is
+equivalent to Python's "magic encoding comment", as described in
+`pep-0263 <http://www.python.org/dev/peps/pep-0263/>`_. Any
+template that contains non-ASCII characters requires that this
+comment be present so that Mako can decode to unicode (and also
+make usage of Python's AST parsing services). Mako's lexer will
+use this encoding in order to convert the template source into a
+``unicode`` object before continuing its parsing:
+
+.. sourcecode:: mako
+
+    ## -*- coding: utf-8 -*-
+
+    Alors vous imaginez ma surprise, au lever du jour, quand 
+    une drôle de petite voix m’a réveillé. Elle disait:
+     « S’il vous plaît… dessine-moi un mouton! »
+
+For the picky, the regular expression used is derived from that
+of the above mentioned pep:
+
+.. sourcecode:: python
+
+    #.*coding[:=]\s*([-\w.]+).*\n
+
+The lexer will convert to unicode in all cases, so that if any
+characters exist in the template that are outside of the
+specified encoding (or the default of ``ascii``), the error will
+be immediate.
+
+As an alternative, the template encoding can be specified
+programmatically to either :class:`.Template` or :class:`.TemplateLookup` via
+the ``input_encoding`` parameter:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['./'], input_encoding='utf-8')
+
+The above will assume all located templates specify ``utf-8``
+encoding, unless the template itself contains its own magic
+encoding comment, which takes precedence.
+
+.. _handling_non_ascii_expressions:
+
+Handling Expressions
+====================
+
+The next area that encoding comes into play is in expression
+constructs. By default, Mako's treatment of an expression like
+this:
+
+.. sourcecode:: mako
+
+    ${"hello world"}
+
+looks something like this:
+
+.. sourcecode:: python
+
+    context.write(unicode("hello world"))
+
+In Python 3, it's just:
+
+.. sourcecode:: python
+
+    context.write(str("hello world"))
+
+That is, **the output of all expressions is run through the
+``unicode`` built-in**. This is the default setting, and can be
+modified to expect various encodings. The ``unicode`` step serves
+both the purpose of rendering non-string expressions into
+strings (such as integers or objects which contain ``__str()__``
+methods), and to ensure that the final output stream is
+constructed as a unicode object. The main implication of this is
+that **any raw byte-strings that contain an encoding other than
+ASCII must first be decoded to a Python unicode object**. It
+means you can't say this in Python 2:
+
+.. sourcecode:: mako
+
+    ${"voix m’a réveillé."}  ## error in Python 2!
+
+You must instead say this:
+
+.. sourcecode:: mako
+
+    ${u"voix m’a réveillé."}  ## OK !
+
+Similarly, if you are reading data from a file that is streaming
+bytes, or returning data from some object that is returning a
+Python byte-string containing a non-ASCII encoding, you have to
+explicitly decode to unicode first, such as:
+
+.. sourcecode:: mako
+
+    ${call_my_object().decode('utf-8')}
+
+Note that filehandles acquired by ``open()`` in Python 3 default
+to returning "text", that is the decoding is done for you. See
+Python 3's documentation for the ``open()`` built-in for details on
+this.
+
+If you want a certain encoding applied to *all* expressions,
+override the ``unicode`` builtin with the ``decode`` built-in at the
+:class:`.Template` or :class:`.TemplateLookup` level:
+
+.. sourcecode:: python
+
+    t = Template(templatetext, default_filters=['decode.utf8'])
+
+Note that the built-in ``decode`` object is slower than the
+``unicode`` function, since unlike ``unicode`` it's not a Python
+built-in, and it also checks the type of the incoming data to
+determine if string conversion is needed first.
+
+The ``default_filters`` argument can be used to entirely customize
+the filtering process of expressions. This argument is described
+in :ref:`filtering_default_filters`.
+
+.. _defining_output_encoding:
+
+Defining Output Encoding
+========================
+
+Now that we have a template which produces a pure unicode output
+stream, all the hard work is done. We can take the output and do
+anything with it.
+
+As stated in the :doc:`"Usage" chapter <usage>`, both :class:`.Template` and
+:class:`.TemplateLookup` accept ``output_encoding`` and ``encoding_errors``
+parameters which can be used to encode the output in any Python
+supported codec:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
+
+    mytemplate = mylookup.get_template("foo.txt")
+    print mytemplate.render()
+
+:meth:`~.Template.render` will return a ``bytes`` object in Python 3 if an output
+encoding is specified. By default it performs no encoding and
+returns a native string.
+
+:meth:`~.Template.render_unicode` will return the template output as a Python
+``unicode`` object (or ``string`` in Python 3):
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode()
+
+The above method disgards the output encoding keyword argument;
+you can encode yourself by saying:
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode().encode('utf-8', 'replace')
+
+Buffer Selection
+----------------
+
+Mako does play some games with the style of buffering used
+internally, to maximize performance. Since the buffer is by far
+the most heavily used object in a render operation, it's
+important!
+
+When calling :meth:`~.Template.render` on a template that does not specify any
+output encoding (i.e. it's ``ascii``), Python's ``cStringIO`` module,
+which cannot handle encoding of non-ASCII ``unicode`` objects
+(even though it can send raw byte-strings through), is used for
+buffering. Otherwise, a custom Mako class called
+``FastEncodingBuffer`` is used, which essentially is a super
+dumbed-down version of ``StringIO`` that gathers all strings into
+a list and uses ``u''.join(elements)`` to produce the final output
+-- it's markedly faster than ``StringIO``.
+
+.. _unicode_disabled:
+
+Saying to Heck with It: Disabling the Usage of Unicode Entirely
+===============================================================
+
+Some segments of Mako's userbase choose to make no usage of
+Unicode whatsoever, and instead would prefer the "pass through"
+approach; all string expressions in their templates return
+encoded byte-strings, and they would like these strings to pass
+right through. The only advantage to this approach is that
+templates need not use ``u""`` for literal strings; there's an
+arguable speed improvement as well since raw byte-strings
+generally perform slightly faster than unicode objects in
+Python. For these users, assuming they're sticking with Python
+2, they can hit the ``disable_unicode=True`` flag as so:
+
+.. sourcecode:: python
+
+    # -*- encoding:utf-8 -*-
+    from mako.template import Template
+
+    t = Template("drôle de petite voix m’a réveillé.", disable_unicode=True, input_encoding='utf-8')
+    print t.code
+
+The ``disable_unicode`` mode is strictly a Python 2 thing. It is
+not supported at all in Python 3.
+
+The generated module source code will contain elements like
+these:
+
+.. sourcecode:: python
+
+    # -*- encoding:utf-8 -*-
+    #  ...more generated code ...
+
+    def render_body(context,**pageargs):
+        context.caller_stack.push_frame()
+        try:
+            __M_locals = dict(pageargs=pageargs)
+            # SOURCE LINE 1
+            context.write('dr\xc3\xb4le de petite voix m\xe2\x80\x99a r\xc3\xa9veill\xc3\xa9.')
+            return ''
+        finally:
+            context.caller_stack.pop_frame()
+
+Where above that the string literal used within :meth:`.Context.write`
+is a regular byte-string.
+
+When ``disable_unicode=True`` is turned on, the ``default_filters``
+argument which normally defaults to ``["unicode"]`` now defaults
+to ``["str"]`` instead. Setting ``default_filters`` to the empty list
+``[]`` can remove the overhead of the ``str`` call. Also, in this
+mode you **cannot** safely call :meth:`~.Template.render_unicode` -- you'll get
+unicode/decode errors.
+
+The ``h`` filter (HTML escape) uses a less performant pure Python
+escape function in non-unicode mode. This because
+MarkupSafe only supports Python unicode objects for non-ASCII
+strings.
+
+.. versionchanged:: 0.3.4
+   In prior versions, it used ``cgi.escape()``, which has been replaced
+   with a function that also escapes single quotes.
+
+Rules for using ``disable_unicode=True``
+----------------------------------------
+
+* Don't use this mode unless you really, really want to and you
+  absolutely understand what you're doing.
+* Don't use this option just because you don't want to learn to
+  use Unicode properly; we aren't supporting user issues in this
+  mode of operation. We will however offer generous help for the
+  vast majority of users who stick to the Unicode program.
+* Python 3 is unicode by default, and the flag is not available
+  when running on Python 3.
+
diff --git a/lib3/Mako-0.7.3/doc/build/usage.rst b/lib3/Mako-0.7.3/doc/build/usage.rst
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/build/usage.rst
@@ -0,0 +1,520 @@
+.. _usage_toplevel:
+
+=====
+Usage
+=====
+
+Basic Usage
+===========
+
+This section describes the Python API for Mako templates. If you
+are using Mako within a web framework such as Pylons, the work
+of integrating Mako's API is already done for you, in which case
+you can skip to the next section, :ref:`syntax_toplevel`.
+
+The most basic way to create a template and render it is through
+the :class:`.Template` class:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    mytemplate = Template("hello world!")
+    print mytemplate.render()
+
+Above, the text argument to :class:`.Template` is **compiled** into a
+Python module representation. This module contains a function
+called ``render_body()``, which produces the output of the
+template. When ``mytemplate.render()`` is called, Mako sets up a
+runtime environment for the template and calls the
+``render_body()`` function, capturing the output into a buffer and
+returning its string contents.
+
+
+The code inside the ``render_body()`` function has access to a
+namespace of variables. You can specify these variables by
+sending them as additional keyword arguments to the :meth:`~.Template.render`
+method:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    mytemplate = Template("hello, ${name}!")
+    print mytemplate.render(name="jack")
+
+The :meth:`~.Template.render` method calls upon Mako to create a
+:class:`.Context` object, which stores all the variable names accessible
+to the template and also stores a buffer used to capture output.
+You can create this :class:`.Context` yourself and have the template
+render with it, using the :meth:`~.Template.render_context` method:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.runtime import Context
+    from StringIO import StringIO
+
+    mytemplate = Template("hello, ${name}!")
+    buf = StringIO()
+    ctx = Context(buf, name="jack")
+    mytemplate.render_context(ctx)
+    print buf.getvalue()
+
+Using File-Based Templates
+==========================
+
+A :class:`.Template` can also load its template source code from a file,
+using the ``filename`` keyword argument:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    mytemplate = Template(filename='/docs/mytmpl.txt')
+    print mytemplate.render()
+
+For improved performance, a :class:`.Template` which is loaded from a
+file can also cache the source code to its generated module on
+the filesystem as a regular Python module file (i.e. a ``.py``
+file). To do this, just add the ``module_directory`` argument to
+the template:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+
+    mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules')
+    print mytemplate.render()
+
+When the above code is rendered, a file
+``/tmp/mako_modules/docs/mytmpl.txt.py`` is created containing the
+source code for the module. The next time a :class:`.Template` with the
+same arguments is created, this module file will be
+automatically re-used.
+
+.. _usage_templatelookup:
+
+Using ``TemplateLookup``
+========================
+
+All of the examples thus far have dealt with the usage of a
+single :class:`.Template` object. If the code within those templates
+tries to locate another template resource, it will need some way
+to find them, using simple URI strings. For this need, the
+resolution of other templates from within a template is
+accomplished by the :class:`.TemplateLookup` class. This class is
+constructed given a list of directories in which to search for
+templates, as well as keyword arguments that will be passed to
+the :class:`.Template` objects it creates:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    mylookup = TemplateLookup(directories=['/docs'])
+    mytemplate = Template("""<%include file="header.txt"/> hello world!""", lookup=mylookup)
+
+Above, we created a textual template which includes the file
+``"header.txt"``. In order for it to have somewhere to look for
+``"header.txt"``, we passed a :class:`.TemplateLookup` object to it, which
+will search in the directory ``/docs`` for the file ``"header.txt"``.
+
+Usually, an application will store most or all of its templates
+as text files on the filesystem. So far, all of our examples
+have been a little bit contrived in order to illustrate the
+basic concepts. But a real application would get most or all of
+its templates directly from the :class:`.TemplateLookup`, using the
+aptly named :meth:`~.TemplateLookup.get_template` method, which accepts the URI of the
+desired template:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules')
+
+    def serve_template(templatename, **kwargs):
+        mytemplate = mylookup.get_template(templatename)
+        print mytemplate.render(**kwargs)
+
+In the example above, we create a :class:`.TemplateLookup` which will
+look for templates in the ``/docs`` directory, and will store
+generated module files in the ``/tmp/mako_modules`` directory. The
+lookup locates templates by appending the given URI to each of
+its search directories; so if you gave it a URI of
+``/etc/beans/info.txt``, it would search for the file
+``/docs/etc/beans/info.txt``, else raise a :class:`.TopLevelNotFound`
+exception, which is a custom Mako exception.
+
+When the lookup locates templates, it will also assign a ``uri``
+property to the :class:`.Template` which is the URI passed to the
+:meth:`~.TemplateLookup.get_template()` call. :class:`.Template` uses this URI to calculate the
+name of its module file. So in the above example, a
+``templatename`` argument of ``/etc/beans/info.txt`` will create a
+module file ``/tmp/mako_modules/etc/beans/info.txt.py``.
+
+Setting the Collection Size
+---------------------------
+
+The :class:`.TemplateLookup` also serves the important need of caching a
+fixed set of templates in memory at a given time, so that
+successive URI lookups do not result in full template
+compilations and/or module reloads on each request. By default,
+the :class:`.TemplateLookup` size is unbounded. You can specify a fixed
+size using the ``collection_size`` argument:
+
+.. sourcecode:: python
+
+    mylookup = TemplateLookup(directories=['/docs'],
+                    module_directory='/tmp/mako_modules', collection_size=500)
+
+The above lookup will continue to load templates into memory
+until it reaches a count of around 500. At that point, it will
+clean out a certain percentage of templates using a least
+recently used scheme.
+
+Setting Filesystem Checks
+-------------------------
+
+Another important flag on :class:`.TemplateLookup` is
+``filesystem_checks``. This defaults to ``True``, and says that each
+time a template is returned by the :meth:`~.TemplateLookup.get_template()` method, the
+revision time of the original template file is checked against
+the last time the template was loaded, and if the file is newer
+will reload its contents and recompile the template. On a
+production system, setting ``filesystem_checks`` to ``False`` can
+afford a small to moderate performance increase (depending on
+the type of filesystem used).
+
+.. _usage_unicode:
+
+Using Unicode and Encoding
+==========================
+
+Both :class:`.Template` and :class:`.TemplateLookup` accept ``output_encoding``
+and ``encoding_errors`` parameters which can be used to encode the
+output in any Python supported codec:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
+
+    mytemplate = mylookup.get_template("foo.txt")
+    print mytemplate.render()
+
+When using Python 3, the :meth:`~.Template.render` method will return a ``bytes``
+object, **if** ``output_encoding`` is set. Otherwise it returns a
+``string``.
+
+Additionally, the :meth:`~.Template.render_unicode()` method exists which will
+return the template output as a Python ``unicode`` object, or in
+Python 3 a ``string``:
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode()
+
+The above method disregards the output encoding keyword
+argument; you can encode yourself by saying:
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode().encode('utf-8', 'replace')
+
+Note that Mako's ability to return data in any encoding and/or
+``unicode`` implies that the underlying output stream of the
+template is a Python unicode object. This behavior is described
+fully in :ref:`unicode_toplevel`.
+
+.. _handling_exceptions:
+
+Handling Exceptions
+===================
+
+Template exceptions can occur in two distinct places. One is
+when you **lookup, parse and compile** the template, the other
+is when you **run** the template. Within the running of a
+template, exceptions are thrown normally from whatever Python
+code originated the issue. Mako has its own set of exception
+classes which mostly apply to the lookup and lexer/compiler
+stages of template construction. Mako provides some library
+routines that can be used to help provide Mako-specific
+information about any exception's stack trace, as well as
+formatting the exception within textual or HTML format. In all
+cases, the main value of these handlers is that of converting
+Python filenames, line numbers, and code samples into Mako
+template filenames, line numbers, and code samples. All lines
+within a stack trace which correspond to a Mako template module
+will be converted to be against the originating template file.
+
+To format exception traces, the :func:`.text_error_template` and
+:func:`.html_error_template` functions are provided. They make usage of
+``sys.exc_info()`` to get at the most recently thrown exception.
+Usage of these handlers usually looks like:
+
+.. sourcecode:: python
+
+    from mako import exceptions
+
+    try:
+        template = lookup.get_template(uri)
+        print template.render()
+    except:
+        print exceptions.text_error_template().render()
+
+Or for the HTML render function:
+
+.. sourcecode:: python
+
+    from mako import exceptions
+
+    try:
+        template = lookup.get_template(uri)
+        print template.render()
+    except:
+        print exceptions.html_error_template().render()
+
+The :func:`.html_error_template` template accepts two options:
+specifying ``full=False`` causes only a section of an HTML
+document to be rendered. Specifying ``css=False`` will disable the
+default stylesheet from being rendered.
+
+E.g.:
+
+.. sourcecode:: python
+
+    print exceptions.html_error_template().render(full=False)
+
+The HTML render function is also available built-in to
+:class:`.Template` using the ``format_exceptions`` flag. In this case, any
+exceptions raised within the **render** stage of the template
+will result in the output being substituted with the output of
+:func:`.html_error_template`:
+
+.. sourcecode:: python
+
+    template = Template(filename="/foo/bar", format_exceptions=True)
+    print template.render()
+
+Note that the compile stage of the above template occurs when
+you construct the :class:`.Template` itself, and no output stream is
+defined. Therefore exceptions which occur within the
+lookup/parse/compile stage will not be handled and will
+propagate normally. While the pre-render traceback usually will
+not include any Mako-specific lines anyway, it will mean that
+exceptions which occur previous to rendering and those which
+occur within rendering will be handled differently... so the
+``try``/``except`` patterns described previously are probably of more
+general use.
+
+The underlying object used by the error template functions is
+the :class:`.RichTraceback` object. This object can also be used
+directly to provide custom error views. Here's an example usage
+which describes its general API:
+
+.. sourcecode:: python
+
+    from mako.exceptions import RichTraceback
+
+    try:
+        template = lookup.get_template(uri)
+        print template.render()
+    except:
+        traceback = RichTraceback()
+        for (filename, lineno, function, line) in traceback.traceback:
+            print "File %s, line %s, in %s" % (filename, lineno, function)
+            print line, "\n"
+        print "%s: %s" % (str(traceback.error.__class__.__name__), traceback.error)
+
+Common Framework Integrations
+=============================
+
+The Mako distribution includes a little bit of helper code for
+the purpose of using Mako in some popular web framework
+scenarios. This is a brief description of what's included.
+
+WSGI
+----
+
+A sample WSGI application is included in the distribution in the
+file ``examples/wsgi/run_wsgi.py``. This runner is set up to pull
+files from a `templates` as well as an `htdocs` directory and
+includes a rudimental two-file layout. The WSGI runner acts as a
+fully functional standalone web server, using ``wsgiutils`` to run
+itself, and propagates GET and POST arguments from the request
+into the :class:`.Context`, can serve images, CSS files and other kinds
+of files, and also displays errors using Mako's included
+exception-handling utilities.
+
+Pygments
+--------
+
+A `Pygments <http://pygments.pocoo.org>`_-compatible syntax
+highlighting module is included under :mod:`mako.ext.pygmentplugin`.
+This module is used in the generation of Mako documentation and
+also contains various `setuptools` entry points under the heading
+``pygments.lexers``, including ``mako``, ``html+mako``, ``xml+mako``
+(see the ``setup.py`` file for all the entry points).
+
+Babel
+-----
+
+Mako provides support for extracting `gettext` messages from
+templates via a `Babel`_ extractor
+entry point under ``mako.ext.babelplugin``.
+
+`Gettext` messages are extracted from all Python code sections,
+including those of control lines and expressions embedded
+in tags.
+
+`Translator
+comments <http://babel.edgewall.org/wiki/Documentation/messages.html#comments-tags-and-translator-comments-explanation>`_
+may also be extracted from Mako templates when a comment tag is
+specified to `Babel`_ (such as with
+the ``-c`` option).
+
+For example, a project ``"myproj"`` contains the following Mako
+template at ``myproj/myproj/templates/name.html``:
+
+.. sourcecode:: mako
+
+    <div id="name">
+      Name:
+      ## TRANSLATORS: This is a proper name. See the gettext
+      ## manual, section Names.
+      ${_('Francois Pinard')}
+    </div>
+
+To extract gettext messages from this template the project needs
+a Mako section in its `Babel Extraction Method Mapping
+file <http://babel.edgewall.org/wiki/Documentation/messages.html#extraction-method-mapping-and-configuration>`_
+(typically located at ``myproj/babel.cfg``):
+
+.. sourcecode:: cfg
+
+    # Extraction from Python source files
+
+    [python: myproj/**.py]
+
+    # Extraction from Mako templates
+
+    [mako: myproj/templates/**.html]
+    input_encoding = utf-8
+
+The Mako extractor supports an optional ``input_encoding``
+parameter specifying the encoding of the templates (identical to
+:class:`.Template`/:class:`.TemplateLookup`'s ``input_encoding`` parameter).
+
+Invoking `Babel`_'s extractor at the
+command line in the project's root directory:
+
+.. sourcecode:: sh
+
+    myproj$ pybabel extract -F babel.cfg -c "TRANSLATORS:" .
+
+will output a `gettext` catalog to `stdout` including the following:
+
+.. sourcecode:: pot
+
+    #. TRANSLATORS: This is a proper name. See the gettext
+    #. manual, section Names.
+    #: myproj/templates/name.html:5
+    msgid "Francois Pinard"
+    msgstr ""
+
+This is only a basic example:
+`Babel`_ can be invoked from ``setup.py``
+and its command line options specified in the accompanying
+``setup.cfg`` via `Babel Distutils/Setuptools
+Integration <http://babel.edgewall.org/wiki/Documentation/setup.html>`_.
+
+Comments must immediately precede a `gettext` message to be
+extracted. In the following case the ``TRANSLATORS:`` comment would
+not have been extracted:
+
+.. sourcecode:: mako
+
+    <div id="name">
+      ## TRANSLATORS: This is a proper name. See the gettext
+      ## manual, section Names.
+      Name: ${_('Francois Pinard')}
+    </div>
+
+See the `Babel User
+Guide <http://babel.edgewall.org/wiki/Documentation/index.html>`_
+for more information.
+
+.. _babel: http://babel.edgewall.org/
+
+
+API Reference
+=============
+
+.. autoclass:: mako.template.Template
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.template.DefTemplate
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.lookup.TemplateCollection
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.lookup.TemplateLookup
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.exceptions.RichTraceback
+    :show-inheritance:
+
+    .. py:attribute:: error
+
+       the exception instance.
+
+    .. py:attribute:: message
+
+       the exception error message as unicode.
+
+    .. py:attribute:: source
+
+       source code of the file where the error occurred.
+       If the error occurred within a compiled template,
+       this is the template source.
+
+    .. py:attribute:: lineno
+
+       line number where the error occurred.  If the error
+       occurred within a compiled template, the line number
+       is adjusted to that of the template source.
+
+    .. py:attribute:: records
+
+       a list of 8-tuples containing the original
+       python traceback elements, plus the
+       filename, line number, source line, and full template source
+       for the traceline mapped back to its originating source
+       template, if any for that traceline (else the fields are ``None``).
+
+    .. py:attribute:: reverse_records
+
+       the list of records in reverse
+       traceback -- a list of 4-tuples, in the same format as a regular
+       python traceback, with template-corresponding
+       traceback records replacing the originals.
+
+    .. py:attribute:: reverse_traceback
+
+       the traceback list in reverse.
+
+.. autofunction:: mako.exceptions.html_error_template
+
+.. autofunction:: mako.exceptions.text_error_template
+
diff --git a/lib3/Mako-0.7.3/doc/caching.html b/lib3/Mako-0.7.3/doc/caching.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/caching.html
@@ -0,0 +1,779 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+                Caching
+             — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+        <link rel="prev" title="The Unicode Chapter" href="unicode.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Prev:
+            <a href="unicode.html" title="previous chapter">The Unicode Chapter</a>
+            </li>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/caching.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+                Caching
+             
+
+        <h2>
+            
+                Caching
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+    <div id="docs-sidebar">
+    <h3><a href="index.html">Table of Contents</a></h3>
+    <ul>
+<li><a class="reference internal" href="#">Caching</a><ul>
+<li><a class="reference internal" href="#cache-arguments">Cache Arguments</a><ul>
+<li><a class="reference internal" href="#backend-specific-cache-arguments">Backend-Specific Cache Arguments</a></li>
+<li><a class="reference internal" href="#using-the-beaker-cache-backend">Using the Beaker Cache Backend</a></li>
+<li><a class="reference internal" href="#using-the-dogpile-cache-backend">Using the dogpile.cache Backend</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#programmatic-cache-access">Programmatic Cache Access</a></li>
+<li><a class="reference internal" href="#cache-plugins">Cache Plugins</a><ul>
+<li><a class="reference internal" href="#guidelines-for-writing-cache-plugins">Guidelines for Writing Cache Plugins</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#api-reference">API Reference</a></li>
+</ul>
+</li>
+</ul>
+
+
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="unicode.html" title="previous chapter">The Unicode Chapter</a>
+    </p>
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+
+    <div id="docs-body" class="withsidebar" >
+        
+<div class="section" id="caching">
+<span id="caching-toplevel"></span><h1>Caching<a class="headerlink" href="#caching" title="Permalink to this headline">¶</a></h1>
+<p>Any template or component can be cached using the <tt class="docutils literal"><span class="pre">cache</span></tt>
+argument to the <tt class="docutils literal"><span class="pre"><%page></span></tt>, <tt class="docutils literal"><span class="pre"><%def></span></tt> or <tt class="docutils literal"><span class="pre"><%block></span></tt> directives:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">page</span> <span class="na">cached=</span><span class="s">"True"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="x">template text</span>
+</pre></div>
+</div>
+<p>The above template, after being executed the first time, will
+store its content within a cache that by default is scoped
+within memory. Subsequent calls to the template’s <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a>
+method will return content directly from the cache. When the
+<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object itself falls out of scope, its corresponding
+cache is garbage collected along with the template.</p>
+<p>By default, caching requires that the <a class="reference external" href="http://beaker.readthedocs.org/">Beaker</a> package be installed on the
+system, however the mechanism of caching can be customized to use
+any third party or user defined system – see <a class="reference internal" href="#cache-plugins"><em>Cache Plugins</em></a>.</p>
+<p>In addition to being available on the <tt class="docutils literal"><span class="pre"><%page></span></tt> tag, the caching flag and all
+its options can be used with the <tt class="docutils literal"><span class="pre"><%def></span></tt> tag as well:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"mycomp"</span> <span class="na">cached=</span><span class="s">"True"</span> <span class="na">cache_timeout=</span><span class="s">"60"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    other text</span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>... and equivalently with the <tt class="docutils literal"><span class="pre"><%block></span></tt> tag, anonymous or named:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">block</span> <span class="na">cached=</span><span class="s">"True"</span> <span class="na">cache_timeout=</span><span class="s">"60"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    other text</span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<div class="section" id="cache-arguments">
+<h2>Cache Arguments<a class="headerlink" href="#cache-arguments" title="Permalink to this headline">¶</a></h2>
+<p>Mako has two cache arguments available on tags that are
+available in all cases.   The rest of the arguments
+available are specific to a backend.</p>
+<p>The two generic tags arguments are:</p>
+<ul>
+<li><p class="first"><tt class="docutils literal"><span class="pre">cached="True"</span></tt> - enable caching for this <tt class="docutils literal"><span class="pre"><%page></span></tt>,
+<tt class="docutils literal"><span class="pre"><%def></span></tt>, or <tt class="docutils literal"><span class="pre"><%block></span></tt>.</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">cache_key</span></tt> - the “key” used to uniquely identify this content
+in the cache.   Usually, this key is chosen automatically
+based on the name of the rendering callable (i.e. <tt class="docutils literal"><span class="pre">body</span></tt>
+when used in <tt class="docutils literal"><span class="pre"><%page></span></tt>, the name of the def when using <tt class="docutils literal"><span class="pre"><%def></span></tt>,
+the explicit or internally-generated name when using <tt class="docutils literal"><span class="pre"><%block></span></tt>).
+Using the <tt class="docutils literal"><span class="pre">cache_key</span></tt> parameter, the key can be overridden
+using a fixed or programmatically generated value.</p>
+<p>For example, here’s a page
+that caches any page which inherits from it, based on the
+filename of the calling template:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">page</span> <span class="na">cached=</span><span class="s">"True"</span> <span class="na">cache_key=</span><span class="s">"${self.filename}"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="cp">${</span><span class="nb">next</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span>
+
+<span class="cp">## rest of template</span><span class="x"></span>
+</pre></div>
+</div>
+</li>
+</ul>
+<p>On a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> or <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>, the
+caching can be configured using these arguments:</p>
+<ul>
+<li><p class="first"><tt class="docutils literal"><span class="pre">cache_enabled</span></tt> - Setting this
+to <tt class="docutils literal"><span class="pre">False</span></tt> will disable all caching functionality
+when the template renders.  Defaults to <tt class="docutils literal"><span class="pre">True</span></tt>.
+e.g.:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span>
+                <span class="n">directories</span><span class="o">=</span><span class="s">'/path/to/templates'</span><span class="p">,</span>
+                <span class="n">cache_enabled</span> <span class="o">=</span> <span class="bp">False</span>
+                <span class="p">)</span>
+</pre></div>
+</div>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">cache_impl</span></tt> - The string name of the cache backend
+to use.   This defaults to <tt class="docutils literal"><span class="pre">'beaker'</span></tt>, which has historically
+been the only cache backend supported by Mako.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.6.0.</span></p>
+<p>For example, here’s how to use the upcoming
+<a class="reference external" href="http://dogpilecache.readthedocs.org">dogpile.cache</a>
+backend:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span>
+                <span class="n">directories</span><span class="o">=</span><span class="s">'/path/to/templates'</span><span class="p">,</span>
+                <span class="n">cache_impl</span> <span class="o">=</span> <span class="s">'dogpile.cache'</span><span class="p">,</span>
+                <span class="n">cache_args</span> <span class="o">=</span> <span class="p">{</span><span class="s">'regions'</span><span class="p">:</span><span class="n">my_dogpile_regions</span><span class="p">}</span>
+                <span class="p">)</span>
+</pre></div>
+</div>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">cache_args</span></tt> - A dictionary of cache parameters that
+will be consumed by the cache backend.   See
+<a class="reference internal" href="#beaker-backend"><em>Using the Beaker Cache Backend</em></a> for examples.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.6.0.</span></p>
+</li>
+</ul>
+<div class="section" id="backend-specific-cache-arguments">
+<h3>Backend-Specific Cache Arguments<a class="headerlink" href="#backend-specific-cache-arguments" title="Permalink to this headline">¶</a></h3>
+<p>The <tt class="docutils literal"><span class="pre"><%page></span></tt>, <tt class="docutils literal"><span class="pre"><%def></span></tt>, and <tt class="docutils literal"><span class="pre"><%block></span></tt> tags
+accept any named argument that starts with the prefix <tt class="docutils literal"><span class="pre">"cache_"</span></tt>.
+Those arguments are then packaged up and passed along to the
+underlying caching implementation, minus the <tt class="docutils literal"><span class="pre">"cache_"</span></tt> prefix.</p>
+<p>The actual arguments understood are determined by the backend.</p>
+<ul class="simple">
+<li><a class="reference internal" href="#beaker-backend"><em>Using the Beaker Cache Backend</em></a> - Includes arguments understood by
+Beaker.</li>
+<li><a class="reference internal" href="#dogpile-cache-backend"><em>Using the dogpile.cache Backend</em></a> - Includes arguments understood by
+dogpile.cache.</li>
+</ul>
+</div>
+<div class="section" id="using-the-beaker-cache-backend">
+<span id="beaker-backend"></span><h3>Using the Beaker Cache Backend<a class="headerlink" href="#using-the-beaker-cache-backend" title="Permalink to this headline">¶</a></h3>
+<p>When using Beaker, new implementations will want to make usage
+of <strong>cache regions</strong> so that cache configurations can be maintained
+externally to templates.  These configurations live under
+named “regions” that can be referred to within templates themselves.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.6.0: </span>Support for Beaker cache regions.</p>
+<p>For example, suppose we would like two regions.  One is a “short term”
+region that will store content in a memory-based dictionary,
+expiring after 60 seconds.   The other is a Memcached region,
+where values should expire in five minutes.   To configure
+our <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>, first we get a handle to a
+<a class="reference external" href="http://beaker.readthedocs.org/en/latest/modules/cache.html#beaker.cache.CacheManager" title="(in Beaker v1.6)"><tt class="xref py py-class docutils literal"><span class="pre">beaker.cache.CacheManager</span></tt></a>:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">beaker.cache</span> <span class="kn">import</span> <span class="n">CacheManager</span>
+
+<span class="n">manager</span> <span class="o">=</span> <span class="n">CacheManager</span><span class="p">(</span><span class="n">cache_regions</span><span class="o">=</span><span class="p">{</span>
+    <span class="s">'short_term'</span><span class="p">:{</span>
+        <span class="s">'type'</span><span class="p">:</span> <span class="s">'memory'</span><span class="p">,</span>
+        <span class="s">'expire'</span><span class="p">:</span> <span class="mi">60</span>
+    <span class="p">},</span>
+    <span class="s">'long_term'</span><span class="p">:{</span>
+        <span class="s">'type'</span><span class="p">:</span> <span class="s">'ext:memcached'</span><span class="p">,</span>
+        <span class="s">'url'</span><span class="p">:</span> <span class="s">'127.0.0.1:11211'</span><span class="p">,</span>
+        <span class="s">'expire'</span><span class="p">:</span> <span class="mi">300</span>
+    <span class="p">}</span>
+<span class="p">})</span>
+
+<span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span>
+                <span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/path/to/templates'</span><span class="p">],</span>
+                <span class="n">module_directory</span><span class="o">=</span><span class="s">'/path/to/modules'</span><span class="p">,</span>
+                <span class="n">cache_impl</span><span class="o">=</span><span class="s">'beaker'</span><span class="p">,</span>
+                <span class="n">cache_args</span><span class="o">=</span><span class="p">{</span>
+                    <span class="s">'manager'</span><span class="p">:</span><span class="n">manager</span>
+                <span class="p">}</span>
+        <span class="p">)</span>
+</pre></div>
+</div>
+<p>Our templates can then opt to cache data in one of either region,
+using the <tt class="docutils literal"><span class="pre">cache_region</span></tt> argument.   Such as using <tt class="docutils literal"><span class="pre">short_term</span></tt>
+at the <tt class="docutils literal"><span class="pre"><%page></span></tt> level:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">page</span> <span class="na">cached=</span><span class="s">"True"</span> <span class="na">cache_region=</span><span class="s">"short_term"</span><span class="cp">></span>
+
+<span class="cp">## ...</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Or, <tt class="docutils literal"><span class="pre">long_term</span></tt> at the <tt class="docutils literal"><span class="pre"><%block></span></tt> level:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span> <span class="na">cached=</span><span class="s">"True"</span> <span class="na">cache_region=</span><span class="s">"long_term"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    other text</span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The Beaker backend also works without regions.   There are a
+variety of arguments that can be passed to the <tt class="docutils literal"><span class="pre">cache_args</span></tt>
+dictionary, which are also allowable in templates via the
+<tt class="docutils literal"><span class="pre"><%page></span></tt>, <tt class="docutils literal"><span class="pre"><%block></span></tt>,
+and <tt class="docutils literal"><span class="pre"><%def></span></tt> tags specific to those sections.   The values
+given override those specified at the  <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>
+or <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> level.</p>
+<p>With the possible exception
+of <tt class="docutils literal"><span class="pre">cache_timeout</span></tt>, these arguments are probably better off
+staying at the template configuration level.  Each argument
+specified as <tt class="docutils literal"><span class="pre">cache_XYZ</span></tt> in a template tag is specified
+without the <tt class="docutils literal"><span class="pre">cache_</span></tt> prefix in the <tt class="docutils literal"><span class="pre">cache_args</span></tt> dictionary:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">cache_timeout</span></tt> - number of seconds in which to invalidate the
+cached data.  After this timeout, the content is re-generated
+on the next call.  Available as <tt class="docutils literal"><span class="pre">timeout</span></tt> in the <tt class="docutils literal"><span class="pre">cache_args</span></tt>
+dictionary.</li>
+<li><tt class="docutils literal"><span class="pre">cache_type</span></tt> - type of caching. <tt class="docutils literal"><span class="pre">'memory'</span></tt>, <tt class="docutils literal"><span class="pre">'file'</span></tt>, <tt class="docutils literal"><span class="pre">'dbm'</span></tt>, or
+<tt class="docutils literal"><span class="pre">'ext:memcached'</span></tt> (note that  the string <tt class="docutils literal"><span class="pre">memcached</span></tt> is
+also accepted by the dogpile.cache Mako plugin, though not by Beaker itself).
+Available as <tt class="docutils literal"><span class="pre">type</span></tt> in the <tt class="docutils literal"><span class="pre">cache_args</span></tt> dictionary.</li>
+<li><tt class="docutils literal"><span class="pre">cache_url</span></tt> - (only used for <tt class="docutils literal"><span class="pre">memcached</span></tt> but required) a single
+IP address or a semi-colon separated list of IP address of
+memcache servers to use.  Available as <tt class="docutils literal"><span class="pre">url</span></tt> in the <tt class="docutils literal"><span class="pre">cache_args</span></tt>
+dictionary.</li>
+<li><tt class="docutils literal"><span class="pre">cache_dir</span></tt> - in the case of the <tt class="docutils literal"><span class="pre">'file'</span></tt> and <tt class="docutils literal"><span class="pre">'dbm'</span></tt> cache types,
+this is the filesystem directory with which to store data
+files. If this option is not present, the value of
+<tt class="docutils literal"><span class="pre">module_directory</span></tt> is used (i.e. the directory where compiled
+template modules are stored). If neither option is available
+an exception is thrown.  Available as <tt class="docutils literal"><span class="pre">dir</span></tt> in the
+<tt class="docutils literal"><span class="pre">cache_args</span></tt> dictionary.</li>
+</ul>
+</div>
+<div class="section" id="using-the-dogpile-cache-backend">
+<span id="dogpile-cache-backend"></span><h3>Using the dogpile.cache Backend<a class="headerlink" href="#using-the-dogpile-cache-backend" title="Permalink to this headline">¶</a></h3>
+<p><a class="reference external" href="http://dogpilecache.readthedocs.org">dogpile.cache</a> is a new replacement for Beaker.   It provides
+a modernized, slimmed down interface and is generally easier to use
+than Beaker.   As of this writing it has not yet been released.  dogpile.cache
+includes its own Mako cache plugin – see <a class="reference external" href="http://dogpilecache.readthedocs.org/en/latest/api.html#dogpile.cache.plugins.mako_cache" title="(in dogpile.cache v0.4.0)"><tt class="xref py py-mod docutils literal"><span class="pre">dogpile.cache.plugins.mako_cache</span></tt></a> in the
+dogpile.cache documentation.</p>
+</div>
+</div>
+<div class="section" id="programmatic-cache-access">
+<h2>Programmatic Cache Access<a class="headerlink" href="#programmatic-cache-access" title="Permalink to this headline">¶</a></h2>
+<p>The <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>, as well as any template-derived <a class="reference internal" href="namespaces.html#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>, has
+an accessor called <tt class="docutils literal"><span class="pre">cache</span></tt> which returns the <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a> object
+for that template. This object is a facade on top of the underlying
+<a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> object, and provides some very rudimental
+capabilities, such as the ability to get and put arbitrary
+values:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span>
+    <span class="n">local</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s">"somekey"</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="s">"memory"</span><span class="p">,</span> <span class="s">"somevalue"</span><span class="p">)</span>
+<span class="cp">%></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Above, the cache associated with the <tt class="docutils literal"><span class="pre">local</span></tt> namespace is
+accessed and a key is placed within a memory cache.</p>
+<p>More commonly, the <tt class="docutils literal"><span class="pre">cache</span></tt> object is used to invalidate cached
+sections programmatically:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">template</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">'/sometemplate.html'</span><span class="p">)</span>
+
+<span class="c"># invalidate the "body" of the template</span>
+<span class="n">template</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">invalidate_body</span><span class="p">()</span>
+
+<span class="c"># invalidate an individual def</span>
+<span class="n">template</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">invalidate_def</span><span class="p">(</span><span class="s">'somedef'</span><span class="p">)</span>
+
+<span class="c"># invalidate an arbitrary key</span>
+<span class="n">template</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">invalidate</span><span class="p">(</span><span class="s">'somekey'</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>You can access any special method or attribute of the <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a>
+itself using the <a class="reference internal" href="#mako.cache.Cache.impl" title="mako.cache.Cache.impl"><tt class="xref py py-attr docutils literal"><span class="pre">impl</span></tt></a> attribute:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">template</span><span class="o">.</span><span class="n">cache</span><span class="o">.</span><span class="n">impl</span><span class="o">.</span><span class="n">do_something_special</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>Note that using implementation-specific methods will mean you can’t
+swap in a different kind of <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> implementation at a
+later time.</p>
+</div>
+<div class="section" id="cache-plugins">
+<span id="id1"></span><h2>Cache Plugins<a class="headerlink" href="#cache-plugins" title="Permalink to this headline">¶</a></h2>
+<p>The mechanism used by caching can be plugged in
+using a <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> subclass.    This class implements
+the rudimental methods Mako needs to implement the caching
+API.   Mako includes the <a class="reference internal" href="#mako.ext.beaker_cache.BeakerCacheImpl" title="mako.ext.beaker_cache.BeakerCacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">BeakerCacheImpl</span></tt></a> class to
+provide the default implementation.  A <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> class
+is acquired by Mako using a <tt class="docutils literal"><span class="pre">pkg_resources</span></tt> entrypoint, using
+the name given as the <tt class="docutils literal"><span class="pre">cache_impl</span></tt> argument to <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>
+or <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>.    This entry point can be
+installed via the standard <cite>setuptools</cite>/<tt class="docutils literal"><span class="pre">setup()</span></tt> procedure, underneath
+the <cite>EntryPoint</cite> group named <tt class="docutils literal"><span class="pre">"mako.cache"</span></tt>.  It can also be
+installed at runtime via a convenience installer <a class="reference internal" href="#mako.cache.register_plugin" title="mako.cache.register_plugin"><tt class="xref py py-func docutils literal"><span class="pre">register_plugin()</span></tt></a>
+which accomplishes essentially the same task.</p>
+<p>An example plugin that implements a local dictionary cache:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.cache</span> <span class="kn">import</span> <span class="n">Cacheimpl</span><span class="p">,</span> <span class="n">register_plugin</span>
+
+<span class="k">class</span> <span class="nc">SimpleCacheImpl</span><span class="p">(</span><span class="n">CacheImpl</span><span class="p">):</span>
+    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cache</span><span class="p">):</span>
+        <span class="nb">super</span><span class="p">(</span><span class="n">SimpleCacheImpl</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">cache</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span> <span class="o">=</span> <span class="p">{}</span>
+
+    <span class="k">def</span> <span class="nf">get_or_create</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">creation_function</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
+        <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">:</span>
+            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
+        <span class="k">else</span><span class="p">:</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span> <span class="o">=</span> <span class="n">creation_function</span><span class="p">()</span>
+            <span class="k">return</span> <span class="n">value</span>
+
+    <span class="k">def</span> <span class="nf">set</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
+
+    <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
+
+    <span class="k">def</span> <span class="nf">invalidate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">_cache</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
+
+<span class="c"># optional - register the class locally</span>
+<span class="n">register_plugin</span><span class="p">(</span><span class="s">"simple"</span><span class="p">,</span> <span class="n">__name__</span><span class="p">,</span> <span class="s">"SimpleCacheImpl"</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Enabling the above plugin in a template would look like:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s">"mytemplate"</span><span class="p">,</span>
+             <span class="nb">file</span><span class="o">=</span><span class="s">"mytemplate.html"</span><span class="p">,</span>
+             <span class="n">cache_impl</span><span class="o">=</span><span class="s">'simple'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="section" id="guidelines-for-writing-cache-plugins">
+<h3>Guidelines for Writing Cache Plugins<a class="headerlink" href="#guidelines-for-writing-cache-plugins" title="Permalink to this headline">¶</a></h3>
+<ul class="simple">
+<li>The <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> is created on a per-<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> basis.  The
+class should ensure that only data for the parent <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> is
+persisted or returned by the cache methods.    The actual <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>
+is available via the <tt class="docutils literal"><span class="pre">self.cache.template</span></tt> attribute.   The <tt class="docutils literal"><span class="pre">self.cache.id</span></tt>
+attribute, which is essentially the unique modulename of the template, is
+a good value to use in order to represent a unique namespace of keys specific
+to the template.</li>
+<li>Templates only use the <a class="reference internal" href="#mako.cache.CacheImpl.get_or_create" title="mako.cache.CacheImpl.get_or_create"><tt class="xref py py-meth docutils literal"><span class="pre">CacheImpl.get_or_create()</span></tt></a> method
+in an implicit fashion.  The <a class="reference internal" href="#mako.cache.CacheImpl.set" title="mako.cache.CacheImpl.set"><tt class="xref py py-meth docutils literal"><span class="pre">CacheImpl.set()</span></tt></a>,
+<a class="reference internal" href="#mako.cache.CacheImpl.get" title="mako.cache.CacheImpl.get"><tt class="xref py py-meth docutils literal"><span class="pre">CacheImpl.get()</span></tt></a>, and <a class="reference internal" href="#mako.cache.CacheImpl.invalidate" title="mako.cache.CacheImpl.invalidate"><tt class="xref py py-meth docutils literal"><span class="pre">CacheImpl.invalidate()</span></tt></a> methods are
+only used in response to direct programmatic access to the corresponding
+methods on the <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a> object.</li>
+<li><a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> will be accessed in a multithreaded fashion if the
+<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> itself is used multithreaded.  Care should be taken
+to ensure caching implementations are threadsafe.</li>
+<li>A library like <a class="reference external" href="http://pypi.python.org/pypi/dogpile.core">Dogpile</a>, which
+is a minimal locking system derived from Beaker, can be used to help
+implement the <a class="reference internal" href="#mako.cache.CacheImpl.get_or_create" title="mako.cache.CacheImpl.get_or_create"><tt class="xref py py-meth docutils literal"><span class="pre">CacheImpl.get_or_create()</span></tt></a> method in a threadsafe
+way that can maximize effectiveness across multiple threads as well
+as processes. <a class="reference internal" href="#mako.cache.CacheImpl.get_or_create" title="mako.cache.CacheImpl.get_or_create"><tt class="xref py py-meth docutils literal"><span class="pre">CacheImpl.get_or_create()</span></tt></a> is the
+key method used by templates.</li>
+<li>All arguments passed to <tt class="docutils literal"><span class="pre">**kw</span></tt> come directly from the parameters
+inside the <tt class="docutils literal"><span class="pre"><%def></span></tt>, <tt class="docutils literal"><span class="pre"><%block></span></tt>, or <tt class="docutils literal"><span class="pre"><%page></span></tt> tags directly,
+minus the <tt class="docutils literal"><span class="pre">"cache_"</span></tt> prefix, as strings, with the exception of
+the argument <tt class="docutils literal"><span class="pre">cache_timeout</span></tt>, which is passed to the plugin
+as the name <tt class="docutils literal"><span class="pre">timeout</span></tt> with the value converted to an integer.
+Arguments present in <tt class="docutils literal"><span class="pre">cache_args</span></tt> on <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> or
+<a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> are passed directly, but are superseded
+by those present in the most specific template tag.</li>
+<li>The directory where <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> places module files can
+be acquired using the accessor <tt class="docutils literal"><span class="pre">self.cache.template.module_directory</span></tt>.
+This directory can be a good place to throw cache-related work
+files, underneath a prefix like <tt class="docutils literal"><span class="pre">_my_cache_work</span></tt> so that name
+conflicts with generated modules don’t occur.</li>
+</ul>
+</div>
+</div>
+<div class="section" id="api-reference">
+<h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="mako.cache.Cache">
+<em class="property">class </em><tt class="descclassname">mako.cache.</tt><tt class="descname">Cache</tt><big>(</big><em>template</em>, <em>*args</em><big>)</big><a class="headerlink" href="#mako.cache.Cache" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
+<p>Represents a data content cache made available to the module
+space of a specific <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.6: </span><a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a> by itself is mostly a
+container for a <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> object, which implements
+a fixed API to provide caching services; specific subclasses exist to
+implement different
+caching strategies.   Mako includes a backend that works with
+the Beaker caching system.   Beaker itself then supports
+a number of backends (i.e. file, memory, memcached, etc.)</p>
+<p>The construction of a <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a> is part of the mechanics
+of a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>, and programmatic access to this
+cache is typically via the <tt class="xref py py-attr docutils literal"><span class="pre">Template.cache</span></tt> attribute.</p>
+<dl class="method">
+<dt id="mako.cache.Cache.get">
+<tt class="descname">get</tt><big>(</big><em>key</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#mako.cache.Cache.get" title="Permalink to this definition">¶</a></dt>
+<dd><p>Retrieve a value from the cache.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>key</strong> – the value’s key.</li>
+<li><strong>**kw</strong> – cache configuration arguments.  The
+backend is configured using these arguments upon first request.
+Subsequent requests that use the same series of configuration
+values will use that same backend.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.Cache.get_or_create">
+<tt class="descname">get_or_create</tt><big>(</big><em>key</em>, <em>creation_function</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#mako.cache.Cache.get_or_create" title="Permalink to this definition">¶</a></dt>
+<dd><p>Retrieve a value from the cache, using the given creation function
+to generate a new value.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.cache.Cache.id">
+<tt class="descname">id</tt><em class="property"> = None</em><a class="headerlink" href="#mako.cache.Cache.id" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the ‘id’ that identifies this cache.</p>
+<p>This is a value that should be globally unique to the
+<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> associated with this cache, and can
+be used by a caching system to name a local container
+for data specific to this template.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.cache.Cache.impl">
+<tt class="descname">impl</tt><em class="property"> = None</em><a class="headerlink" href="#mako.cache.Cache.impl" title="Permalink to this definition">¶</a></dt>
+<dd><p>Provide the <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> in use by this <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a>.</p>
+<p>This accessor allows a <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> with additional
+methods beyond that of <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a> to be used programmatically.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.Cache.invalidate">
+<tt class="descname">invalidate</tt><big>(</big><em>key</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#mako.cache.Cache.invalidate" title="Permalink to this definition">¶</a></dt>
+<dd><p>Invalidate a value in the cache.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>key</strong> – the value’s key.</li>
+<li><strong>**kw</strong> – cache configuration arguments.  The
+backend is configured using these arguments upon first request.
+Subsequent requests that use the same series of configuration
+values will use that same backend.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.Cache.invalidate_body">
+<tt class="descname">invalidate_body</tt><big>(</big><big>)</big><a class="headerlink" href="#mako.cache.Cache.invalidate_body" title="Permalink to this definition">¶</a></dt>
+<dd><p>Invalidate the cached content of the “body” method for this
+template.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.Cache.invalidate_closure">
+<tt class="descname">invalidate_closure</tt><big>(</big><em>name</em><big>)</big><a class="headerlink" href="#mako.cache.Cache.invalidate_closure" title="Permalink to this definition">¶</a></dt>
+<dd><p>Invalidate a nested <tt class="docutils literal"><span class="pre"><%def></span></tt> within this template.</p>
+<p>Caching of nested defs is a blunt tool as there is no
+management of scope – nested defs that use cache tags
+need to have names unique of all other nested defs in the
+template, else their content will be overwritten by
+each other.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.Cache.invalidate_def">
+<tt class="descname">invalidate_def</tt><big>(</big><em>name</em><big>)</big><a class="headerlink" href="#mako.cache.Cache.invalidate_def" title="Permalink to this definition">¶</a></dt>
+<dd><p>Invalidate the cached content of a particular <tt class="docutils literal"><span class="pre"><%def></span></tt> within this
+template.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.Cache.put">
+<tt class="descname">put</tt><big>(</big><em>key</em>, <em>value</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#mako.cache.Cache.put" title="Permalink to this definition">¶</a></dt>
+<dd><p>A synonym for <a class="reference internal" href="#mako.cache.Cache.set" title="mako.cache.Cache.set"><tt class="xref py py-meth docutils literal"><span class="pre">Cache.set()</span></tt></a>.</p>
+<p>This is here for backwards compatibility.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.Cache.set">
+<tt class="descname">set</tt><big>(</big><em>key</em>, <em>value</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#mako.cache.Cache.set" title="Permalink to this definition">¶</a></dt>
+<dd><p>Place a value in the cache.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>key</strong> – the value’s key.</li>
+<li><strong>value</strong> – the value.</li>
+<li><strong>**kw</strong> – cache configuration arguments.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.cache.Cache.starttime">
+<tt class="descname">starttime</tt><em class="property"> = None</em><a class="headerlink" href="#mako.cache.Cache.starttime" title="Permalink to this definition">¶</a></dt>
+<dd><p>Epochal time value for when the owning <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> was
+first compiled.</p>
+<p>A cache implementation may wish to invalidate data earlier than
+this timestamp; this has the effect of the cache for a specific
+<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> starting clean any time the <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>
+is recompiled, such as when the original template file changed on
+the filesystem.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="mako.cache.CacheImpl">
+<em class="property">class </em><tt class="descclassname">mako.cache.</tt><tt class="descname">CacheImpl</tt><big>(</big><em>cache</em><big>)</big><a class="headerlink" href="#mako.cache.CacheImpl" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
+<p>Provide a cache implementation for use by <a class="reference internal" href="#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a>.</p>
+<dl class="method">
+<dt id="mako.cache.CacheImpl.get">
+<tt class="descname">get</tt><big>(</big><em>key</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#mako.cache.CacheImpl.get" title="Permalink to this definition">¶</a></dt>
+<dd><p>Retrieve a value from the cache.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>key</strong> – the value’s key.</li>
+<li><strong>**kw</strong> – cache configuration arguments.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.CacheImpl.get_or_create">
+<tt class="descname">get_or_create</tt><big>(</big><em>key</em>, <em>creation_function</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#mako.cache.CacheImpl.get_or_create" title="Permalink to this definition">¶</a></dt>
+<dd><p>Retrieve a value from the cache, using the given creation function
+to generate a new value.</p>
+<p>This function <em>must</em> return a value, either from
+the cache, or via the given creation function.
+If the creation function is called, the newly
+created value should be populated into the cache
+under the given key before being returned.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>key</strong> – the value’s key.</li>
+<li><strong>creation_function</strong> – function that when called generates
+a new value.</li>
+<li><strong>**kw</strong> – cache configuration arguments.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.CacheImpl.invalidate">
+<tt class="descname">invalidate</tt><big>(</big><em>key</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#mako.cache.CacheImpl.invalidate" title="Permalink to this definition">¶</a></dt>
+<dd><p>Invalidate a value in the cache.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>key</strong> – the value’s key.</li>
+<li><strong>**kw</strong> – cache configuration arguments.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.cache.CacheImpl.pass_context">
+<tt class="descname">pass_context</tt><em class="property"> = False</em><a class="headerlink" href="#mako.cache.CacheImpl.pass_context" title="Permalink to this definition">¶</a></dt>
+<dd><p>If <tt class="docutils literal"><span class="pre">True</span></tt>, the <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> will be passed to
+<a class="reference internal" href="#mako.cache.CacheImpl.get_or_create" title="mako.cache.CacheImpl.get_or_create"><tt class="xref py py-meth docutils literal"><span class="pre">get_or_create</span></tt></a> as the name <tt class="docutils literal"><span class="pre">'context'</span></tt>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.cache.CacheImpl.set">
+<tt class="descname">set</tt><big>(</big><em>key</em>, <em>value</em>, <em>**kw</em><big>)</big><a class="headerlink" href="#mako.cache.CacheImpl.set" title="Permalink to this definition">¶</a></dt>
+<dd><p>Place a value in the cache.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>key</strong> – the value’s key.</li>
+<li><strong>value</strong> – the value.</li>
+<li><strong>**kw</strong> – cache configuration arguments.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="mako.cache.register_plugin">
+<tt class="descclassname">mako.cache.</tt><tt class="descname">register_plugin</tt><big>(</big><em>self</em>, <em>name</em>, <em>modulepath</em>, <em>objname</em><big>)</big><a class="headerlink" href="#mako.cache.register_plugin" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<dl class="class">
+<dt id="mako.ext.beaker_cache.BeakerCacheImpl">
+<em class="property">class </em><tt class="descclassname">mako.ext.beaker_cache.</tt><tt class="descname">BeakerCacheImpl</tt><big>(</big><em>cache</em><big>)</big><a class="headerlink" href="#mako.ext.beaker_cache.BeakerCacheImpl" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">mako.cache.CacheImpl</span></tt></a></p>
+<p>A <a class="reference internal" href="#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> provided for the Beaker caching system.</p>
+<p>This plugin is used by default, based on the default
+value of <tt class="docutils literal"><span class="pre">'beaker'</span></tt> for the <tt class="docutils literal"><span class="pre">cache_impl</span></tt> parameter of the
+<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> or <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> classes.</p>
+</dd></dl>
+
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Previous:
+        <a href="unicode.html" title="previous chapter">The Unicode Chapter</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/defs.html b/lib3/Mako-0.7.3/doc/defs.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/defs.html
@@ -0,0 +1,728 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+                Defs and Blocks
+             — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+        <link rel="next" title="The Mako Runtime Environment" href="runtime.html" />
+        <link rel="prev" title="Syntax" href="syntax.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Prev:
+            <a href="syntax.html" title="previous chapter">Syntax</a>
+            </li>
+            <li>Next:
+            <a href="runtime.html" title="next chapter">The Mako Runtime Environment</a>
+            </li>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/defs.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+                Defs and Blocks
+             
+
+        <h2>
+            
+                Defs and Blocks
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+    <div id="docs-sidebar">
+    <h3><a href="index.html">Table of Contents</a></h3>
+    <ul>
+<li><a class="reference internal" href="#">Defs and Blocks</a><ul>
+<li><a class="reference internal" href="#using-defs">Using Defs</a><ul>
+<li><a class="reference internal" href="#calling-defs-from-other-files">Calling Defs from Other Files</a></li>
+<li><a class="reference internal" href="#calling-defs-programmatically">Calling Defs Programmatically</a></li>
+<li><a class="reference internal" href="#defs-within-defs">Defs within Defs</a></li>
+<li><a class="reference internal" href="#calling-a-def-with-embedded-content-and-or-other-defs">Calling a Def with Embedded Content and/or Other Defs</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#using-blocks">Using Blocks</a><ul>
+<li><a class="reference internal" href="#using-named-blocks">Using Named Blocks</a></li>
+<li><a class="reference internal" href="#using-page-arguments-in-named-blocks">Using Page Arguments in Named Blocks</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+
+
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="syntax.html" title="previous chapter">Syntax</a>
+    </p>
+    <h4>Next Topic</h4>
+    <p>
+    <a href="runtime.html" title="next chapter">The Mako Runtime Environment</a>
+    </p>
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+
+    <div id="docs-body" class="withsidebar" >
+        
+<div class="section" id="defs-and-blocks">
+<span id="defs-toplevel"></span><h1>Defs and Blocks<a class="headerlink" href="#defs-and-blocks" title="Permalink to this headline">¶</a></h1>
+<p><tt class="docutils literal"><span class="pre"><%def></span></tt> and <tt class="docutils literal"><span class="pre"><%block></span></tt> are two tags that both demarcate any block of text
+and/or code.   They both exist within generated Python as a callable function,
+i.e., a Python <tt class="docutils literal"><span class="pre">def</span></tt>.   They differ in their scope and calling semantics.
+Whereas <tt class="docutils literal"><span class="pre"><%def></span></tt> provides a construct that is very much like a named Python
+<tt class="docutils literal"><span class="pre">def</span></tt>, the <tt class="docutils literal"><span class="pre"><%block></span></tt> is more layout oriented.</p>
+<div class="section" id="using-defs">
+<h2>Using Defs<a class="headerlink" href="#using-defs" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre"><%def></span></tt> tag requires a <tt class="docutils literal"><span class="pre">name</span></tt> attribute, where the <tt class="docutils literal"><span class="pre">name</span></tt> references
+a Python function signature:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"hello()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    hello world</span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>To invoke the <tt class="docutils literal"><span class="pre"><%def></span></tt>, it is normally called as an expression:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x">the def:  </span><span class="cp">${</span><span class="n">hello</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>If the <tt class="docutils literal"><span class="pre"><%def></span></tt> is not nested inside of another <tt class="docutils literal"><span class="pre"><%def></span></tt>,
+it’s known as a <strong>top level def</strong> and can be accessed anywhere in
+the template, including above where it was defined.</p>
+<p>All defs, top level or not, have access to the current
+contextual namespace in exactly the same way their containing
+template does. Suppose the template below is executed with the
+variables <tt class="docutils literal"><span class="pre">username</span></tt> and <tt class="docutils literal"><span class="pre">accountdata</span></tt> inside the context:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x">Hello there </span><span class="cp">${</span><span class="n">username</span><span class="cp">}</span><span class="x">, how are ya.  Lets see what your account says:</span>
+
+<span class="cp">${</span><span class="n">account</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"account()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    Account for </span><span class="cp">${</span><span class="n">username</span><span class="cp">}</span><span class="x">:<br/></span>
+
+    <span class="cp">%</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">accountdata</span><span class="p">:</span><span class="x"></span>
+<span class="x">        Value: </span><span class="cp">${</span><span class="n">row</span><span class="cp">}</span><span class="x"><br/></span>
+    <span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre">username</span></tt> and <tt class="docutils literal"><span class="pre">accountdata</span></tt> variables are present
+within the main template body as well as the body of the
+<tt class="docutils literal"><span class="pre">account()</span></tt> def.</p>
+<p>Since defs are just Python functions, you can define and pass
+arguments to them as well:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="n">account</span><span class="p">(</span><span class="n">accountname</span><span class="o">=</span><span class="s">'john'</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"account(accountname, type='regular')"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    account name: </span><span class="cp">${</span><span class="n">accountname</span><span class="cp">}</span><span class="x">, type: </span><span class="cp">${</span><span class="nb">type</span><span class="cp">}</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>When you declare an argument signature for your def, they are
+required to follow normal Python conventions (i.e., all
+arguments are required except keyword arguments with a default
+value). This is in contrast to using context-level variables,
+which evaluate to <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> if you reference a name that
+does not exist.</p>
+<div class="section" id="calling-defs-from-other-files">
+<h3>Calling Defs from Other Files<a class="headerlink" href="#calling-defs-from-other-files" title="Permalink to this headline">¶</a></h3>
+<p>Top level <tt class="docutils literal"><span class="pre"><%def></span></tt>s are <strong>exported</strong> by your template’s
+module, and can be called from the outside; including from other
+templates, as well as normal Python code. Calling a <tt class="docutils literal"><span class="pre"><%def></span></tt>
+from another template is something like using an <tt class="docutils literal"><span class="pre"><%include></span></tt>
+– except you are calling a specific function within the
+template, not the whole template.</p>
+<p>The remote <tt class="docutils literal"><span class="pre"><%def></span></tt> call is also a little bit like calling
+functions from other modules in Python. There is an “import”
+step to pull the names from another template into your own
+template; then the function or functions are available.</p>
+<p>To import another template, use the <tt class="docutils literal"><span class="pre"><%namespace></span></tt> tag:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">namespace</span> <span class="na">name=</span><span class="s">"mystuff"</span> <span class="na">file=</span><span class="s">"mystuff.html"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The above tag adds a local variable <tt class="docutils literal"><span class="pre">mystuff</span></tt> to the current
+scope.</p>
+<p>Then, just call the defs off of <tt class="docutils literal"><span class="pre">mystuff</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="n">mystuff</span><span class="o">.</span><span class="n">somedef</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span><span class="n">y</span><span class="o">=</span><span class="mi">7</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre"><%namespace></span></tt> tag also supports some of the other
+semantics of Python’s <tt class="docutils literal"><span class="pre">import</span></tt> statement, including pulling
+names into the local variable space, or using <tt class="docutils literal"><span class="pre">*</span></tt> to represent
+all names, using the <tt class="docutils literal"><span class="pre">import</span></tt> attribute:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">namespace</span> <span class="na">file=</span><span class="s">"mystuff.html"</span> <span class="na">import=</span><span class="s">"foo, bar"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>This is just a quick intro to the concept of a <strong>namespace</strong>,
+which is a central Mako concept that has its own chapter in
+these docs. For more detail and examples, see
+<a class="reference internal" href="namespaces.html"><em>Namespaces</em></a>.</p>
+</div>
+<div class="section" id="calling-defs-programmatically">
+<h3>Calling Defs Programmatically<a class="headerlink" href="#calling-defs-programmatically" title="Permalink to this headline">¶</a></h3>
+<p>You can call defs programmatically from any <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object
+using the <a class="reference internal" href="usage.html#mako.template.Template.get_def" title="mako.template.Template.get_def"><tt class="xref py py-meth docutils literal"><span class="pre">get_def()</span></tt></a> method, which returns a <a class="reference internal" href="usage.html#mako.template.DefTemplate" title="mako.template.DefTemplate"><tt class="xref py py-class docutils literal"><span class="pre">DefTemplate</span></tt></a>
+object. This is a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> subclass which the parent
+<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> creates, and is usable like any other template:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+
+<span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s">"""</span>
+<span class="s">    <</span><span class="si">%d</span><span class="s">ef name="hi(name)"></span>
+<span class="s">        hi ${name}!</span>
+<span class="s">    </</span><span class="si">%d</span><span class="s">ef></span>
+
+<span class="s">    <</span><span class="si">%d</span><span class="s">ef name="bye(name)"></span>
+<span class="s">        bye ${name}!</span>
+<span class="s">    </</span><span class="si">%d</span><span class="s">ef></span>
+<span class="s">"""</span><span class="p">)</span>
+
+<span class="k">print</span> <span class="n">template</span><span class="o">.</span><span class="n">get_def</span><span class="p">(</span><span class="s">"hi"</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">"ed"</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">template</span><span class="o">.</span><span class="n">get_def</span><span class="p">(</span><span class="s">"bye"</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">"ed"</span><span class="p">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="defs-within-defs">
+<h3>Defs within Defs<a class="headerlink" href="#defs-within-defs" title="Permalink to this headline">¶</a></h3>
+<p>The def model follows regular Python rules for closures.
+Declaring <tt class="docutils literal"><span class="pre"><%def></span></tt> inside another <tt class="docutils literal"><span class="pre"><%def></span></tt> declares it
+within the parent’s <strong>enclosing scope</strong>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"mydef()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"subdef()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        a sub def</span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="x">    i'm the def, and the subcomponent is </span><span class="cp">${</span><span class="n">subdef</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Just like Python, names that exist outside the inner <tt class="docutils literal"><span class="pre"><%def></span></tt>
+exist inside it as well:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span>
+    <span class="n">x</span> <span class="o">=</span> <span class="mi">12</span>
+<span class="cp">%></span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"outer()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span>
+        <span class="n">y</span> <span class="o">=</span> <span class="mi">15</span>
+    <span class="cp">%></span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"inner()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        inner, x is </span><span class="cp">${</span><span class="n">x</span><span class="cp">}</span><span class="x">, y is </span><span class="cp">${</span><span class="n">y</span><span class="cp">}</span><span class="x"></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="x">    outer, x is </span><span class="cp">${</span><span class="n">x</span><span class="cp">}</span><span class="x">, y is </span><span class="cp">${</span><span class="n">y</span><span class="cp">}</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Assigning to a name inside of a def declares that name as local
+to the scope of that def (again, like Python itself). This means
+the following code will raise an error:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span>
+    <span class="n">x</span> <span class="o">=</span> <span class="mi">10</span>
+<span class="cp">%></span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"somedef()"</span><span class="cp">></span>
+    <span class="cp">## error !</span><span class="x"></span>
+<span class="x">    somedef, x is </span><span class="cp">${</span><span class="n">x</span><span class="cp">}</span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span>
+        <span class="n">x</span> <span class="o">=</span> <span class="mi">27</span>
+    <span class="cp">%></span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>...because the assignment to <tt class="docutils literal"><span class="pre">x</span></tt> declares <tt class="docutils literal"><span class="pre">x</span></tt> as local to the
+scope of <tt class="docutils literal"><span class="pre">somedef</span></tt>, rendering the “outer” version unreachable
+in the expression that tries to render it.</p>
+</div>
+<div class="section" id="calling-a-def-with-embedded-content-and-or-other-defs">
+<span id="defs-with-content"></span><h3>Calling a Def with Embedded Content and/or Other Defs<a class="headerlink" href="#calling-a-def-with-embedded-content-and-or-other-defs" title="Permalink to this headline">¶</a></h3>
+<p>A flip-side to def within def is a def call with content. This
+is where you call a def, and at the same time declare a block of
+content (or multiple blocks) that can be used by the def being
+called. The main point of such a call is to create custom,
+nestable tags, just like any other template language’s
+custom-tag creation system – where the external tag controls the
+execution of the nested tags and can communicate state to them.
+Only with Mako, you don’t have to use any external Python
+modules, you can define arbitrarily nestable tags right in your
+templates.</p>
+<p>To achieve this, the target def is invoked using the form
+<tt class="docutils literal"><span class="pre"><%namepacename:defname></span></tt> instead of the normal <tt class="docutils literal"><span class="pre">${}</span></tt>
+syntax. This syntax, introduced in Mako 0.2.3, is functionally
+equivalent to another tag known as <tt class="docutils literal"><span class="pre">%call</span></tt>, which takes the form
+<tt class="docutils literal"><span class="pre"><%call</span> <span class="pre">expr='namespacename.defname(args)'></span></tt>. While <tt class="docutils literal"><span class="pre">%call</span></tt>
+is available in all versions of Mako, the newer style is
+probably more familiar looking. The <tt class="docutils literal"><span class="pre">namespace</span></tt> portion of the
+call is the name of the <strong>namespace</strong> in which the def is
+defined – in the most simple cases, this can be <tt class="docutils literal"><span class="pre">local</span></tt> or
+<tt class="docutils literal"><span class="pre">self</span></tt> to reference the current template’s namespace (the
+difference between <tt class="docutils literal"><span class="pre">local</span></tt> and <tt class="docutils literal"><span class="pre">self</span></tt> is one of inheritance
+– see <a class="reference internal" href="namespaces.html#namespaces-builtin"><em>Built-in Namespaces</em></a> for details).</p>
+<p>When the target def is invoked, a variable <tt class="docutils literal"><span class="pre">caller</span></tt> is placed
+in its context which contains another namespace containing the
+body and other defs defined by the caller. The body itself is
+referenced by the method <tt class="docutils literal"><span class="pre">body()</span></tt>. Below, we build a <tt class="docutils literal"><span class="pre">%def</span></tt>
+that operates upon <tt class="docutils literal"><span class="pre">caller.body()</span></tt> to invoke the body of the
+custom tag:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"buildtable()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    <table></span>
+<span class="x">        <tr><td></span>
+<span class="x">            </span><span class="cp">${</span><span class="n">caller</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">        </td></tr></span>
+<span class="x">    </table></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">self:buildtable</span><span class="cp">></span><span class="x"></span>
+<span class="x">    I am the table body.</span>
+<span class="cp"></%</span><span class="nb">self:buildtable</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>This produces the output (whitespace formatted):</p>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><table></span>
+    <span class="nt"><tr><td></span>
+        I am the table body.
+    <span class="nt"></td></tr></span>
+<span class="nt"></table></span>
+</pre></div>
+</div>
+<p>Using the older <tt class="docutils literal"><span class="pre">%call</span></tt> syntax looks like:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"buildtable()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    <table></span>
+<span class="x">        <tr><td></span>
+<span class="x">            </span><span class="cp">${</span><span class="n">caller</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">        </td></tr></span>
+<span class="x">    </table></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">call</span> <span class="na">expr=</span><span class="s">"buildtable()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    I am the table body.</span>
+<span class="cp"></%</span><span class="nb">call</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre">body()</span></tt> can be executed multiple times or not at all.
+This means you can use def-call-with-content to build iterators,
+conditionals, etc:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"lister(count)"</span><span class="cp">></span>
+    <span class="cp">%</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">count</span><span class="p">):</span><span class="x"></span>
+<span class="x">        </span><span class="cp">${</span><span class="n">caller</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span>
+    <span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">self:lister</span> <span class="na">count=</span><span class="s">"${3}"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    hi</span>
+<span class="cp"></%</span><span class="nb">self:lister</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Produces:</p>
+<div class="highlight-html"><div class="highlight"><pre>hi
+hi
+hi
+</pre></div>
+</div>
+<p>Notice above we pass <tt class="docutils literal"><span class="pre">3</span></tt> as a Python expression, so that it
+remains as an integer.</p>
+<p>A custom “conditional” tag:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"conditional(expression)"</span><span class="cp">></span>
+    <span class="cp">%</span> <span class="k">if</span> <span class="n">expression</span><span class="p">:</span><span class="x"></span>
+<span class="x">        </span><span class="cp">${</span><span class="n">caller</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span>
+    <span class="cp">%</span><span class="k"> endif</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">self:conditional</span> <span class="na">expression=</span><span class="s">"${4==4}"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    i'm the result</span>
+<span class="cp"></%</span><span class="nb">self:conditional</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Produces:</p>
+<div class="highlight-html"><div class="highlight"><pre>i'm the result
+</pre></div>
+</div>
+<p>But that’s not all. The <tt class="docutils literal"><span class="pre">body()</span></tt> function also can handle
+arguments, which will augment the local namespace of the body
+callable. The caller must define the arguments which it expects
+to receive from its target def using the <tt class="docutils literal"><span class="pre">args</span></tt> attribute,
+which is a comma-separated list of argument names. Below, our
+<tt class="docutils literal"><span class="pre"><%def></span></tt> calls the <tt class="docutils literal"><span class="pre">body()</span></tt> of its caller, passing in an
+element of data from its argument:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"layoutdata(somedata)"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    <table></span>
+    <span class="cp">%</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">somedata</span><span class="p">:</span><span class="x"></span>
+<span class="x">        <tr></span>
+        <span class="cp">%</span> <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="n">item</span><span class="p">:</span><span class="x"></span>
+<span class="x">            <td></span><span class="cp">${</span><span class="n">caller</span><span class="o">.</span><span class="n">body</span><span class="p">(</span><span class="n">col</span><span class="o">=</span><span class="n">col</span><span class="p">)</span><span class="cp">}</span><span class="x"></td></span>
+        <span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="x">        </tr></span>
+    <span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="x">    </table></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">self:layoutdata</span> <span class="na">somedata=</span><span class="s">"${[[1,2,3],[4,5,6],[7,8,9]]}"</span> <span class="na">args=</span><span class="s">"col"</span><span class="cp">></span><span class="x">\</span>
+<span class="x">Body data: </span><span class="cp">${</span><span class="n">col</span><span class="cp">}</span><span class="x">\</span>
+<span class="cp"></%</span><span class="nb">self:layoutdata</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Produces:</p>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><table></span>
+    <span class="nt"><tr></span>
+        <span class="nt"><td></span>Body data: 1<span class="nt"></td></span>
+        <span class="nt"><td></span>Body data: 2<span class="nt"></td></span>
+        <span class="nt"><td></span>Body data: 3<span class="nt"></td></span>
+    <span class="nt"></tr></span>
+    <span class="nt"><tr></span>
+        <span class="nt"><td></span>Body data: 4<span class="nt"></td></span>
+        <span class="nt"><td></span>Body data: 5<span class="nt"></td></span>
+        <span class="nt"><td></span>Body data: 6<span class="nt"></td></span>
+    <span class="nt"></tr></span>
+    <span class="nt"><tr></span>
+        <span class="nt"><td></span>Body data: 7<span class="nt"></td></span>
+        <span class="nt"><td></span>Body data: 8<span class="nt"></td></span>
+        <span class="nt"><td></span>Body data: 9<span class="nt"></td></span>
+    <span class="nt"></tr></span>
+<span class="nt"></table></span>
+</pre></div>
+</div>
+<p>You don’t have to stick to calling just the <tt class="docutils literal"><span class="pre">body()</span></tt> function.
+The caller can define any number of callables, allowing the
+<tt class="docutils literal"><span class="pre"><%call></span></tt> tag to produce whole layouts:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"layout()"</span><span class="cp">></span>
+    <span class="cp">## a layout def</span><span class="x"></span>
+<span class="x">    <div class="mainlayout"></span>
+<span class="x">        <div class="header"></span>
+<span class="x">            </span><span class="cp">${</span><span class="n">caller</span><span class="o">.</span><span class="n">header</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">        </div></span>
+
+<span class="x">        <div class="sidebar"></span>
+<span class="x">            </span><span class="cp">${</span><span class="n">caller</span><span class="o">.</span><span class="n">sidebar</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">        </div></span>
+
+<span class="x">        <div class="content"></span>
+<span class="x">            </span><span class="cp">${</span><span class="n">caller</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">        </div></span>
+<span class="x">    </div></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span>
+
+<span class="cp">## calls the layout def</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">self:layout</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"header()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        I am the header</span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"sidebar()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        <ul></span>
+<span class="x">            <li>sidebar 1</li></span>
+<span class="x">            <li>sidebar 2</li></span>
+<span class="x">        </ul></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="x">        this is the body</span>
+<span class="cp"></%</span><span class="nb">self:layout</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The above layout would produce:</p>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><div</span> <span class="na">class=</span><span class="s">"mainlayout"</span><span class="nt">></span>
+    <span class="nt"><div</span> <span class="na">class=</span><span class="s">"header"</span><span class="nt">></span>
+    I am the header
+    <span class="nt"></div></span>
+
+    <span class="nt"><div</span> <span class="na">class=</span><span class="s">"sidebar"</span><span class="nt">></span>
+    <span class="nt"><ul></span>
+        <span class="nt"><li></span>sidebar 1<span class="nt"></li></span>
+        <span class="nt"><li></span>sidebar 2<span class="nt"></li></span>
+    <span class="nt"></ul></span>
+    <span class="nt"></div></span>
+
+    <span class="nt"><div</span> <span class="na">class=</span><span class="s">"content"</span><span class="nt">></span>
+    this is the body
+    <span class="nt"></div></span>
+<span class="nt"></div></span>
+</pre></div>
+</div>
+<p>The number of things you can do with <tt class="docutils literal"><span class="pre"><%call></span></tt> and/or the
+<tt class="docutils literal"><span class="pre"><%namespacename:defname></span></tt> calling syntax is enormous. You can
+create form widget libraries, such as an enclosing <tt class="docutils literal"><span class="pre"><FORM></span></tt>
+tag and nested HTML input elements, or portable wrapping schemes
+using <tt class="docutils literal"><span class="pre"><div></span></tt> or other elements. You can create tags that
+interpret rows of data, such as from a database, providing the
+individual columns of each row to a <tt class="docutils literal"><span class="pre">body()</span></tt> callable which
+lays out the row any way it wants. Basically anything you’d do
+with a “custom tag” or tag library in some other system, Mako
+provides via <tt class="docutils literal"><span class="pre"><%def></span></tt> tags and plain Python callables which are
+invoked via <tt class="docutils literal"><span class="pre"><%namespacename:defname></span></tt> or <tt class="docutils literal"><span class="pre"><%call></span></tt>.</p>
+</div>
+</div>
+<div class="section" id="using-blocks">
+<span id="blocks"></span><h2>Using Blocks<a class="headerlink" href="#using-blocks" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre"><%block></span></tt> tag introduces some new twists on the
+<tt class="docutils literal"><span class="pre"><%def></span></tt> tag which make it more closely tailored towards layout.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.4.1.</span></p>
+<p>An example of a block:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><html></span>
+<span class="x">    <body></span>
+<span class="x">        </span><span class="cp"><%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">            this is a block.</span>
+<span class="x">        </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </body></span>
+<span class="x"></html></span>
+</pre></div>
+</div>
+<p>In the above example, we define a simple block.  The block renders its content in the place
+that it’s defined.  Since the block is called for us, it doesn’t need a name and the above
+is referred to as an <strong>anonymous block</strong>.  So the output of the above template will be:</p>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><html></span>
+    <span class="nt"><body></span>
+            this is a block.
+    <span class="nt"></body></span>
+<span class="nt"></html></span>
+</pre></div>
+</div>
+<p>So in fact the above block has absolutely no effect.  Its usefulness comes when we start
+using modifiers.  Such as, we can apply a filter to our block:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><html></span>
+<span class="x">    <body></span>
+<span class="x">        </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">filter=</span><span class="s">"h"</span><span class="cp">></span><span class="x"></span>
+<span class="x">            <html>this is some escaped html.</html></span>
+<span class="x">        </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </body></span>
+<span class="x"></html></span>
+</pre></div>
+</div>
+<p>or perhaps a caching directive:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><html></span>
+<span class="x">    <body></span>
+<span class="x">        </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">cached=</span><span class="s">"True"</span> <span class="na">cache_timeout=</span><span class="s">"60"</span><span class="cp">></span><span class="x"></span>
+<span class="x">            This content will be cached for 60 seconds.</span>
+<span class="x">        </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </body></span>
+<span class="x"></html></span>
+</pre></div>
+</div>
+<p>Blocks also work in iterations, conditionals, just like defs:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">%</span> <span class="k">if</span> <span class="n">some_condition</span><span class="p">:</span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">block</span><span class="cp">></span><span class="x">condition is met</span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span>
+<span class="cp">%</span><span class="k"> endif</span><span class="x"></span>
+</pre></div>
+</div>
+<p>While the block renders at the point it is defined in the template,
+the underlying function is present in the generated Python code only
+once, so there’s no issue with placing a block inside of a loop or
+similar. Anonymous blocks are defined as closures in the local
+rendering body, so have access to local variable scope:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">%</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">):</span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">block</span><span class="cp">></span><span class="x">i is </span><span class="cp">${</span><span class="n">i</span><span class="cp">}</%</span><span class="nb">block</span><span class="cp">></span>
+<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+</pre></div>
+</div>
+<div class="section" id="using-named-blocks">
+<h3>Using Named Blocks<a class="headerlink" href="#using-named-blocks" title="Permalink to this headline">¶</a></h3>
+<p>Possibly the more important area where blocks are useful is when we
+do actually give them names. Named blocks are tailored to behave
+somewhat closely to Jinja2’s block tag, in that they define an area
+of a layout which can be overridden by an inheriting template. In
+sharp contrast to the <tt class="docutils literal"><span class="pre"><%def></span></tt> tag, the name given to a block is
+global for the entire template regardless of how deeply it’s nested:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><html></span>
+<span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    <head></span>
+<span class="x">        <title></span>
+<span class="x">            </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"title"</span><span class="cp">></span><span class="x">Title</span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">        </title></span>
+<span class="x">    </head></span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x"><body></span>
+<span class="x">    </span><span class="cp">${</span><span class="nb">next</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x"></body></span>
+<span class="x"></html></span>
+</pre></div>
+</div>
+<p>The above example has two named blocks “<tt class="docutils literal"><span class="pre">header</span></tt>” and “<tt class="docutils literal"><span class="pre">title</span></tt>”, both of which can be referred to
+by an inheriting template. A detailed walkthrough of this usage can be found at <a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</p>
+<p>Note above that named blocks don’t have any argument declaration the way defs do. They still implement themselves
+as Python functions, however, so they can be invoked additional times beyond their initial definition:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><div name="page"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"pagecontrol"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        <a href="">previous page</a> |</span>
+<span class="x">        <a href="">next page</a></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+
+<span class="x">    <table></span>
+<span class="x">        ## some content</span>
+<span class="x">    </table></span>
+
+<span class="x">    </span><span class="cp">${</span><span class="n">pagecontrol</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x"></div></span>
+</pre></div>
+</div>
+<p>The content referenced by <tt class="docutils literal"><span class="pre">pagecontrol</span></tt> above will be rendered both above and below the <tt class="docutils literal"><span class="pre"><table></span></tt> tags.</p>
+<p>To keep things sane, named blocks have restrictions that defs do not:</p>
+<ul class="simple">
+<li>The <tt class="docutils literal"><span class="pre"><%block></span></tt> declaration cannot have any argument signature.</li>
+<li>The name of a <tt class="docutils literal"><span class="pre"><%block></span></tt> can only be defined once in a template – an error is raised if two blocks of the same
+name occur anywhere in a single template, regardless of nesting.  A similar error is raised if a top level def
+shares the same name as that of a block.</li>
+<li>A named <tt class="docutils literal"><span class="pre"><%block></span></tt> cannot be defined within a <tt class="docutils literal"><span class="pre"><%def></span></tt>, or inside the body of a “call”, i.e.
+<tt class="docutils literal"><span class="pre"><%call></span></tt> or <tt class="docutils literal"><span class="pre"><%namespacename:defname></span></tt> tag.  Anonymous blocks can, however.</li>
+</ul>
+</div>
+<div class="section" id="using-page-arguments-in-named-blocks">
+<h3>Using Page Arguments in Named Blocks<a class="headerlink" href="#using-page-arguments-in-named-blocks" title="Permalink to this headline">¶</a></h3>
+<p>A named block is very much like a top level def. It has a similar
+restriction to these types of defs in that arguments passed to the
+template via the <tt class="docutils literal"><span class="pre"><%page></span></tt> tag aren’t automatically available.
+Using arguments with the <tt class="docutils literal"><span class="pre"><%page></span></tt> tag is described in the section
+<a class="reference internal" href="namespaces.html#namespaces-body"><em>The body() Method</em></a>, and refers to scenarios such as when the
+<tt class="docutils literal"><span class="pre">body()</span></tt> method of a template is called from an inherited template passing
+arguments, or the template is invoked from an <tt class="docutils literal"><span class="pre"><%include></span></tt> tag
+with arguments. To allow a named block to share the same arguments
+passed to the page, the <tt class="docutils literal"><span class="pre">args</span></tt> attribute can be used:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">page</span> <span class="na">args=</span><span class="s">"post"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="x"><a name="</span><span class="cp">${</span><span class="n">post</span><span class="o">.</span><span class="n">title</span><span class="cp">}</span><span class="x">" /></span>
+
+<span class="x"><span class="post_prose"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"post_prose"</span> <span class="na">args=</span><span class="s">"post"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        </span><span class="cp">${</span><span class="n">post</span><span class="o">.</span><span class="n">content</span><span class="cp">}</span><span class="x"></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x"></span></span>
+</pre></div>
+</div>
+<p>Where above, if the template is called via a directive like
+<tt class="docutils literal"><span class="pre"><%include</span> <span class="pre">file="post.mako"</span> <span class="pre">args="post=post"</span> <span class="pre">/></span></tt>, the <tt class="docutils literal"><span class="pre">post</span></tt>
+variable is available both in the main body as well as the
+<tt class="docutils literal"><span class="pre">post_prose</span></tt> block.</p>
+<p>Similarly, the <tt class="docutils literal"><span class="pre">**pageargs</span></tt> variable is present, in named blocks only,
+for those arguments not explicit in the <tt class="docutils literal"><span class="pre"><%page></span></tt> tag:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"post_prose"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </span><span class="cp">${</span><span class="n">pageargs</span><span class="p">[</span><span class="s">'post'</span><span class="p">]</span><span class="o">.</span><span class="n">content</span><span class="cp">}</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre">args</span></tt> attribute is only allowed with named blocks. With
+anonymous blocks, the Python function is always rendered in the same
+scope as the call itself, so anything available directly outside the
+anonymous block is available inside as well.</p>
+</div>
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Previous:
+        <a href="syntax.html" title="previous chapter">Syntax</a>
+        Next:
+        <a href="runtime.html" title="next chapter">The Mako Runtime Environment</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/filtering.html b/lib3/Mako-0.7.3/doc/filtering.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/filtering.html
@@ -0,0 +1,478 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+                Filtering and Buffering
+             — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+        <link rel="next" title="The Unicode Chapter" href="unicode.html" />
+        <link rel="prev" title="Inheritance" href="inheritance.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Prev:
+            <a href="inheritance.html" title="previous chapter">Inheritance</a>
+            </li>
+            <li>Next:
+            <a href="unicode.html" title="next chapter">The Unicode Chapter</a>
+            </li>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/filtering.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+                Filtering and Buffering
+             
+
+        <h2>
+            
+                Filtering and Buffering
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+    <div id="docs-sidebar">
+    <h3><a href="index.html">Table of Contents</a></h3>
+    <ul>
+<li><a class="reference internal" href="#">Filtering and Buffering</a><ul>
+<li><a class="reference internal" href="#expression-filtering">Expression Filtering</a><ul>
+<li><a class="reference internal" href="#the-default-filters-argument">The <tt class="docutils literal"><span class="pre">default_filters</span></tt> Argument</a></li>
+<li><a class="reference internal" href="#turning-off-filtering-with-the-n-filter">Turning off Filtering with the <tt class="docutils literal"><span class="pre">n</span></tt> Filter</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#filtering-defs-and-blocks">Filtering Defs and Blocks</a></li>
+<li><a class="reference internal" href="#buffering">Buffering</a></li>
+<li><a class="reference internal" href="#decorating">Decorating</a></li>
+</ul>
+</li>
+</ul>
+
+
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="inheritance.html" title="previous chapter">Inheritance</a>
+    </p>
+    <h4>Next Topic</h4>
+    <p>
+    <a href="unicode.html" title="next chapter">The Unicode Chapter</a>
+    </p>
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+
+    <div id="docs-body" class="withsidebar" >
+        
+<div class="section" id="filtering-and-buffering">
+<span id="filtering-toplevel"></span><h1>Filtering and Buffering<a class="headerlink" href="#filtering-and-buffering" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="expression-filtering">
+<h2>Expression Filtering<a class="headerlink" href="#expression-filtering" title="Permalink to this headline">¶</a></h2>
+<p>As described in the chapter <a class="reference internal" href="syntax.html"><em>Syntax</em></a>, the “<tt class="docutils literal"><span class="pre">|</span></tt>” operator can be
+applied to a “<tt class="docutils literal"><span class="pre">${}</span></tt>” expression to apply escape filters to the
+output:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">"this is some text"</span> <span class="o">|</span> <span class="n">u</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The above expression applies URL escaping to the expression, and
+produces <tt class="docutils literal"><span class="pre">this+is+some+text</span></tt>.</p>
+<p>The built-in escape flags are:</p>
+<ul>
+<li><p class="first"><tt class="docutils literal"><span class="pre">u</span></tt> : URL escaping, provided by
+<tt class="docutils literal"><span class="pre">urllib.quote_plus(string.encode('utf-8'))</span></tt></p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">h</span></tt> : HTML escaping, provided by
+<tt class="docutils literal"><span class="pre">markupsafe.escape(string)</span></tt></p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.3.4: </span>Prior versions use <tt class="docutils literal"><span class="pre">cgi.escape(string,</span> <span class="pre">True)</span></tt>.</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">x</span></tt> : XML escaping</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">trim</span></tt> : whitespace trimming, provided by <tt class="docutils literal"><span class="pre">string.strip()</span></tt></p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">entity</span></tt> : produces HTML entity references for applicable
+strings, derived from <tt class="docutils literal"><span class="pre">htmlentitydefs</span></tt></p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">unicode</span></tt> (<tt class="docutils literal"><span class="pre">str</span></tt> on Python 3): produces a Python unicode
+string (this function is applied by default)</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">decode.<some</span> <span class="pre">encoding></span></tt>: decode input into a Python
+unicode with the specified encoding</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">n</span></tt> : disable all default filtering; only filters specified
+in the local expression tag will be applied.</p>
+</li>
+</ul>
+<p>To apply more than one filter, separate them by a comma:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">" <tag>some value</tag> "</span> <span class="o">|</span> <span class="n">h</span><span class="p">,</span><span class="n">trim</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The above produces <tt class="docutils literal"><span class="pre">&lt;tag&gt;some</span> <span class="pre">value&lt;/tag&gt;</span></tt>, with
+no leading or trailing whitespace. The HTML escaping function is
+applied first, the “trim” function second.</p>
+<p>Naturally, you can make your own filters too. A filter is just a
+Python function that accepts a single string argument, and
+returns the filtered result. The expressions after the <tt class="docutils literal"><span class="pre">|</span></tt>
+operator draw upon the local namespace of the template in which
+they appear, meaning you can define escaping functions locally:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%!</span>
+    <span class="k">def</span> <span class="nf">myescape</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
+        <span class="k">return</span> <span class="s">"<TAG>"</span> <span class="o">+</span> <span class="n">text</span> <span class="o">+</span> <span class="s">"</TAG>"</span>
+<span class="cp">%></span><span class="x"></span>
+
+<span class="x">Here's some tagged text: </span><span class="cp">${</span><span class="s">"text"</span> <span class="o">|</span> <span class="n">myescape</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Or from any Python module:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%!</span>
+    <span class="kn">import</span> <span class="nn">myfilters</span>
+<span class="cp">%></span><span class="x"></span>
+
+<span class="x">Here's some tagged text: </span><span class="cp">${</span><span class="s">"text"</span> <span class="o">|</span> <span class="n">myfilters</span><span class="o">.</span><span class="n">tagfilter</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>A page can apply a default set of filters to all expression tags
+using the <tt class="docutils literal"><span class="pre">expression_filter</span></tt> argument to the <tt class="docutils literal"><span class="pre">%page</span></tt> tag:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">page</span> <span class="na">expression_filter=</span><span class="s">"h"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="x">Escaped text:  </span><span class="cp">${</span><span class="s">"<html>some html</html>"</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Result:</p>
+<div class="highlight-html"><div class="highlight"><pre>Escaped text: <span class="ni">&lt;</span>html<span class="ni">&gt;</span>some html<span class="ni">&lt;</span>/html<span class="ni">&gt;</span>
+</pre></div>
+</div>
+<div class="section" id="the-default-filters-argument">
+<span id="filtering-default-filters"></span><h3>The <tt class="docutils literal"><span class="pre">default_filters</span></tt> Argument<a class="headerlink" href="#the-default-filters-argument" title="Permalink to this headline">¶</a></h3>
+<p>In addition to the <tt class="docutils literal"><span class="pre">expression_filter</span></tt> argument, the
+<tt class="docutils literal"><span class="pre">default_filters</span></tt> argument to both <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> and
+<a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> can specify filtering for all expression tags
+at the programmatic level. This array-based argument, when given
+its default argument of <tt class="docutils literal"><span class="pre">None</span></tt>, will be internally set to
+<tt class="docutils literal"><span class="pre">["unicode"]</span></tt> (or <tt class="docutils literal"><span class="pre">["str"]</span></tt> on Python 3), except when
+<tt class="docutils literal"><span class="pre">disable_unicode=True</span></tt> is set in which case it defaults to
+<tt class="docutils literal"><span class="pre">["str"]</span></tt>:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">t</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/tmp'</span><span class="p">],</span> <span class="n">default_filters</span><span class="o">=</span><span class="p">[</span><span class="s">'unicode'</span><span class="p">])</span>
+</pre></div>
+</div>
+<p>To replace the usual <tt class="docutils literal"><span class="pre">unicode</span></tt>/<tt class="docutils literal"><span class="pre">str</span></tt> function with a
+specific encoding, the <tt class="docutils literal"><span class="pre">decode</span></tt> filter can be substituted:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">t</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/tmp'</span><span class="p">],</span> <span class="n">default_filters</span><span class="o">=</span><span class="p">[</span><span class="s">'decode.utf8'</span><span class="p">])</span>
+</pre></div>
+</div>
+<p>To disable <tt class="docutils literal"><span class="pre">default_filters</span></tt> entirely, set it to an empty
+list:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">t</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/tmp'</span><span class="p">],</span> <span class="n">default_filters</span><span class="o">=</span><span class="p">[])</span>
+</pre></div>
+</div>
+<p>Any string name can be added to <tt class="docutils literal"><span class="pre">default_filters</span></tt> where it
+will be added to all expressions as a filter. The filters are
+applied from left to right, meaning the leftmost filter is
+applied first.</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">templatetext</span><span class="p">,</span> <span class="n">default_filters</span><span class="o">=</span><span class="p">[</span><span class="s">'unicode'</span><span class="p">,</span> <span class="s">'myfilter'</span><span class="p">])</span>
+</pre></div>
+</div>
+<p>To ease the usage of <tt class="docutils literal"><span class="pre">default_filters</span></tt> with custom filters,
+you can also add imports (or other code) to all templates using
+the <tt class="docutils literal"><span class="pre">imports</span></tt> argument:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">t</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/tmp'</span><span class="p">],</span>
+                   <span class="n">default_filters</span><span class="o">=</span><span class="p">[</span><span class="s">'unicode'</span><span class="p">,</span> <span class="s">'myfilter'</span><span class="p">],</span>
+                   <span class="n">imports</span><span class="o">=</span><span class="p">[</span><span class="s">'from mypackage import myfilter'</span><span class="p">])</span>
+</pre></div>
+</div>
+<p>The above will generate templates something like this:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="c"># ....</span>
+<span class="kn">from</span> <span class="nn">mypackage</span> <span class="kn">import</span> <span class="n">myfilter</span>
+
+<span class="k">def</span> <span class="nf">render_body</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
+    <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">myfilter</span><span class="p">(</span><span class="nb">unicode</span><span class="p">(</span><span class="s">"some text"</span><span class="p">)))</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="turning-off-filtering-with-the-n-filter">
+<h3>Turning off Filtering with the <tt class="docutils literal"><span class="pre">n</span></tt> Filter<a class="headerlink" href="#turning-off-filtering-with-the-n-filter" title="Permalink to this headline">¶</a></h3>
+<p>In all cases the special <tt class="docutils literal"><span class="pre">n</span></tt> filter, used locally within an
+expression, will <strong>disable</strong> all filters declared in the
+<tt class="docutils literal"><span class="pre"><%page></span></tt> tag as well as in <tt class="docutils literal"><span class="pre">default_filters</span></tt>. Such as:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">'myexpression'</span> <span class="o">|</span> <span class="n">n</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>will render <tt class="docutils literal"><span class="pre">myexpression</span></tt> with no filtering of any kind, and:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">'myexpression'</span> <span class="o">|</span> <span class="n">n</span><span class="p">,</span><span class="n">trim</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>will render <tt class="docutils literal"><span class="pre">myexpression</span></tt> using the <tt class="docutils literal"><span class="pre">trim</span></tt> filter only.</p>
+</div>
+</div>
+<div class="section" id="filtering-defs-and-blocks">
+<h2>Filtering Defs and Blocks<a class="headerlink" href="#filtering-defs-and-blocks" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre">%def</span></tt> and <tt class="docutils literal"><span class="pre">%block</span></tt> tags have an argument called <tt class="docutils literal"><span class="pre">filter</span></tt> which will apply the
+given list of filter functions to the output of the <tt class="docutils literal"><span class="pre">%def</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"foo()"</span> <span class="na">filter=</span><span class="s">"h, trim"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    <b>this is bold</b></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>When the <tt class="docutils literal"><span class="pre">filter</span></tt> attribute is applied to a def as above, the def
+is automatically <strong>buffered</strong> as well. This is described next.</p>
+</div>
+<div class="section" id="buffering">
+<h2>Buffering<a class="headerlink" href="#buffering" title="Permalink to this headline">¶</a></h2>
+<p>One of Mako’s central design goals is speed. To this end, all of
+the textual content within a template and its various callables
+is by default piped directly to the single buffer that is stored
+within the <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object. While this normally is easy to
+miss, it has certain side effects. The main one is that when you
+call a def using the normal expression syntax, i.e.
+<tt class="docutils literal"><span class="pre">${somedef()}</span></tt>, it may appear that the return value of the
+function is the content it produced, which is then delivered to
+your template just like any other expression substitution,
+except that normally, this is not the case; the return value of
+<tt class="docutils literal"><span class="pre">${somedef()}</span></tt> is simply the empty string <tt class="docutils literal"><span class="pre">''</span></tt>. By the time
+you receive this empty string, the output of <tt class="docutils literal"><span class="pre">somedef()</span></tt> has
+been sent to the underlying buffer.</p>
+<p>You may not want this effect, if for example you are doing
+something like this:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">" results "</span> <span class="o">+</span> <span class="n">somedef</span><span class="p">()</span> <span class="o">+</span> <span class="s">" more results "</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>If the <tt class="docutils literal"><span class="pre">somedef()</span></tt> function produced the content “<tt class="docutils literal"><span class="pre">somedef's</span>
+<span class="pre">results</span></tt>”, the above template would produce this output:</p>
+<div class="highlight-html"><div class="highlight"><pre>somedef's results results more results
+</pre></div>
+</div>
+<p>This is because <tt class="docutils literal"><span class="pre">somedef()</span></tt> fully executes before the
+expression returns the results of its concatenation; the
+concatenation in turn receives just the empty string as its
+middle expression.</p>
+<p>Mako provides two ways to work around this. One is by applying
+buffering to the <tt class="docutils literal"><span class="pre">%def</span></tt> itself:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"somedef()"</span> <span class="na">buffered=</span><span class="s">"True"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    somedef's results</span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The above definition will generate code similar to this:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">somedef</span><span class="p">():</span>
+    <span class="n">context</span><span class="o">.</span><span class="n">push_buffer</span><span class="p">()</span>
+    <span class="k">try</span><span class="p">:</span>
+        <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"somedef's results"</span><span class="p">)</span>
+    <span class="k">finally</span><span class="p">:</span>
+        <span class="n">buf</span> <span class="o">=</span> <span class="n">context</span><span class="o">.</span><span class="n">pop_buffer</span><span class="p">()</span>
+    <span class="k">return</span> <span class="n">buf</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>So that the content of <tt class="docutils literal"><span class="pre">somedef()</span></tt> is sent to a second buffer,
+which is then popped off the stack and its value returned. The
+speed hit inherent in buffering the output of a def is also
+apparent.</p>
+<p>Note that the <tt class="docutils literal"><span class="pre">filter</span></tt> argument on <tt class="docutils literal"><span class="pre">%def</span></tt> also causes the def to
+be buffered. This is so that the final content of the <tt class="docutils literal"><span class="pre">%def</span></tt> can
+be delivered to the escaping function in one batch, which
+reduces method calls and also produces more deterministic
+behavior for the filtering function itself, which can possibly
+be useful for a filtering function that wishes to apply a
+transformation to the text as a whole.</p>
+<p>The other way to buffer the output of a def or any Mako callable
+is by using the built-in <tt class="docutils literal"><span class="pre">capture</span></tt> function. This function
+performs an operation similar to the above buffering operation
+except it is specified by the caller.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">" results "</span> <span class="o">+</span> <span class="n">capture</span><span class="p">(</span><span class="n">somedef</span><span class="p">)</span> <span class="o">+</span> <span class="s">" more results "</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Note that the first argument to the <tt class="docutils literal"><span class="pre">capture</span></tt> function is
+<strong>the function itself</strong>, not the result of calling it. This is
+because the <tt class="docutils literal"><span class="pre">capture</span></tt> function takes over the job of actually
+calling the target function, after setting up a buffered
+environment. To send arguments to the function, just send them
+to <tt class="docutils literal"><span class="pre">capture</span></tt> instead:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="n">capture</span><span class="p">(</span><span class="n">somedef</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="s">'hi'</span><span class="p">,</span> <span class="n">use_paging</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The above call is equivalent to the unbuffered call:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="n">somedef</span><span class="p">(</span><span class="mi">17</span><span class="p">,</span> <span class="s">'hi'</span><span class="p">,</span> <span class="n">use_paging</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="decorating">
+<h2>Decorating<a class="headerlink" href="#decorating" title="Permalink to this headline">¶</a></h2>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.2.5.</span></p>
+<p>Somewhat like a filter for a <tt class="docutils literal"><span class="pre">%def</span></tt> but more flexible, the <tt class="docutils literal"><span class="pre">decorator</span></tt>
+argument to <tt class="docutils literal"><span class="pre">%def</span></tt> allows the creation of a function that will
+work in a similar manner to a Python decorator. The function can
+control whether or not the function executes. The original
+intent of this function is to allow the creation of custom cache
+logic, but there may be other uses as well.</p>
+<p><tt class="docutils literal"><span class="pre">decorator</span></tt> is intended to be used with a regular Python
+function, such as one defined in a library module. Here we’ll
+illustrate the python function defined in the template for
+simplicities’ sake:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%!</span>
+    <span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
+        <span class="k">def</span> <span class="nf">decorate</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
+            <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"BAR"</span><span class="p">)</span>
+            <span class="n">fn</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
+            <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"BAR"</span><span class="p">)</span>
+            <span class="k">return</span> <span class="s">''</span>
+        <span class="k">return</span> <span class="n">decorate</span>
+<span class="cp">%></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"foo()"</span> <span class="na">decorator=</span><span class="s">"bar"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is foo</span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp">${</span><span class="n">foo</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The above template will return, with more whitespace than this,
+<tt class="docutils literal"><span class="pre">"BAR</span> <span class="pre">this</span> <span class="pre">is</span> <span class="pre">foo</span> <span class="pre">BAR"</span></tt>. The function is the render callable
+itself (or possibly a wrapper around it), and by default will
+write to the context. To capture its output, use the <a class="reference internal" href="namespaces.html#mako.runtime.capture" title="mako.runtime.capture"><tt class="xref py py-func docutils literal"><span class="pre">capture()</span></tt></a>
+callable in the <tt class="docutils literal"><span class="pre">mako.runtime</span></tt> module (available in templates
+as just <tt class="docutils literal"><span class="pre">runtime</span></tt>):</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%!</span>
+    <span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="n">fn</span><span class="p">):</span>
+        <span class="k">def</span> <span class="nf">decorate</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
+            <span class="k">return</span> <span class="s">"BAR"</span> <span class="o">+</span> <span class="n">runtime</span><span class="o">.</span><span class="n">capture</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">fn</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span> <span class="o">+</span> <span class="s">"BAR"</span>
+        <span class="k">return</span> <span class="n">decorate</span>
+<span class="cp">%></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"foo()"</span> <span class="na">decorator=</span><span class="s">"bar"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is foo</span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp">${</span><span class="n">foo</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The decorator can be used with top-level defs as well as nested
+defs, and blocks too. Note that when calling a top-level def from the
+<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> API, i.e. <tt class="docutils literal"><span class="pre">template.get_def('somedef').render()</span></tt>,
+the decorator has to write the output to the <tt class="docutils literal"><span class="pre">context</span></tt>, i.e.
+as in the first example. The return value gets discarded.</p>
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Previous:
+        <a href="inheritance.html" title="previous chapter">Inheritance</a>
+        Next:
+        <a href="unicode.html" title="next chapter">The Unicode Chapter</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/genindex.html b/lib3/Mako-0.7.3/doc/genindex.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/genindex.html
@@ -0,0 +1,916 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+    Index
+ — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="#" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="#">Index</a>
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+    Index
+ 
+
+        <h2>
+            
+    Index
+
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+
+    <div id="docs-body" class="" >
+        
+
+
+
+   <h1 id="index">Index</h1>
+
+    <a href="#A"><strong>A</strong></a>
+    | <a href="#B"><strong>B</strong></a>
+    | <a href="#C"><strong>C</strong></a>
+    | <a href="#D"><strong>D</strong></a>
+    | <a href="#E"><strong>E</strong></a>
+    | <a href="#F"><strong>F</strong></a>
+    | <a href="#G"><strong>G</strong></a>
+    | <a href="#H"><strong>H</strong></a>
+    | <a href="#I"><strong>I</strong></a>
+    | <a href="#K"><strong>K</strong></a>
+    | <a href="#L"><strong>L</strong></a>
+    | <a href="#M"><strong>M</strong></a>
+    | <a href="#N"><strong>N</strong></a>
+    | <a href="#P"><strong>P</strong></a>
+    | <a href="#R"><strong>R</strong></a>
+    | <a href="#S"><strong>S</strong></a>
+    | <a href="#T"><strong>T</strong></a>
+    | <a href="#U"><strong>U</strong></a>
+    | <a href="#W"><strong>W</strong></a>
+
+   <hr />
+
+<h2 id="A">A</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="usage.html#mako.lookup.TemplateCollection.adjust_uri">adjust_uri() (mako.lookup.TemplateCollection method)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="usage.html#mako.lookup.TemplateLookup.adjust_uri">(mako.lookup.TemplateLookup method)</a>
+      </dt>
+    </dl></dd>
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace.attr">attr (mako.runtime.Namespace attribute)</a>
+</dt>
+
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="B">B</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="caching.html#mako.ext.beaker_cache.BeakerCacheImpl">BeakerCacheImpl (class in mako.ext.beaker_cache)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="C">C</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="caching.html#mako.cache.Cache">Cache (class in mako.cache)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace.cache">cache (mako.runtime.Namespace attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="caching.html#mako.cache.CacheImpl">CacheImpl (class in mako.cache)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.capture">capture() (in module mako.runtime)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.template.Template.code">code (mako.template.Template attribute)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="runtime.html#mako.runtime.Context">Context (class in mako.runtime)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace.context">context (mako.runtime.Namespace attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="runtime.html#mako.runtime.LoopContext.cycle">cycle() (mako.runtime.LoopContext method)</a>
+</dt>
+
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="D">D</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="usage.html#mako.template.DefTemplate">DefTemplate (class in mako.template)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="E">E</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="usage.html#RichTraceback.error">error (RichTraceback attribute)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="F">F</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="namespaces.html#mako.runtime.ModuleNamespace.filename">filename (mako.runtime.ModuleNamespace attribute)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="namespaces.html#mako.runtime.Namespace.filename">(mako.runtime.Namespace attribute)</a>
+      </dt>
+      <dt><a href="namespaces.html#mako.runtime.TemplateNamespace.filename">(mako.runtime.TemplateNamespace attribute)</a>
+      </dt>
+    </dl></dd>
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="usage.html#mako.lookup.TemplateCollection.filename_to_uri">filename_to_uri() (mako.lookup.TemplateCollection method)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="usage.html#mako.lookup.TemplateLookup.filename_to_uri">(mako.lookup.TemplateLookup method)</a>
+      </dt>
+    </dl></dd>
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="G">G</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.get">get() (mako.cache.Cache method)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="caching.html#mako.cache.CacheImpl.get">(mako.cache.CacheImpl method)</a>
+      </dt>
+      <dt><a href="runtime.html#mako.runtime.Context.get">(mako.runtime.Context method)</a>
+      </dt>
+    </dl></dd>
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace.get_cached">get_cached() (mako.runtime.Namespace method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.template.Template.get_def">get_def() (mako.template.Template method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace.get_namespace">get_namespace() (mako.runtime.Namespace method)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.get_or_create">get_or_create() (mako.cache.Cache method)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="caching.html#mako.cache.CacheImpl.get_or_create">(mako.cache.CacheImpl method)</a>
+      </dt>
+    </dl></dd>
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.lookup.TemplateCollection.get_template">get_template() (mako.lookup.TemplateCollection method)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="usage.html#mako.lookup.TemplateLookup.get_template">(mako.lookup.TemplateLookup method)</a>
+      </dt>
+      <dt><a href="namespaces.html#mako.runtime.Namespace.get_template">(mako.runtime.Namespace method)</a>
+      </dt>
+    </dl></dd>
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="H">H</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="usage.html#mako.lookup.TemplateCollection.has_template">has_template() (mako.lookup.TemplateCollection method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.exceptions.html_error_template">html_error_template() (in module mako.exceptions)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="I">I</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.id">id (mako.cache.Cache attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.impl">impl (mako.cache.Cache attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace.include_file">include_file() (mako.runtime.Namespace method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.invalidate">invalidate() (mako.cache.Cache method)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="caching.html#mako.cache.CacheImpl.invalidate">(mako.cache.CacheImpl method)</a>
+      </dt>
+    </dl></dd>
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.invalidate_body">invalidate_body() (mako.cache.Cache method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.invalidate_closure">invalidate_closure() (mako.cache.Cache method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.invalidate_def">invalidate_def() (mako.cache.Cache method)</a>
+</dt>
+
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="K">K</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="runtime.html#mako.runtime.Context.keys">keys() (mako.runtime.Context method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="runtime.html#mako.runtime.Context.kwargs">kwargs (mako.runtime.Context attribute)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="L">L</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="usage.html#RichTraceback.lineno">lineno (RichTraceback attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="runtime.html#mako.runtime.Context.locals_">locals_() (mako.runtime.Context method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="runtime.html#mako.runtime.Context.lookup">lookup (mako.runtime.Context attribute)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="runtime.html#mako.runtime.LoopContext">LoopContext (class in mako.runtime)</a>
+</dt>
+
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="M">M</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="usage.html#RichTraceback.message">message (RichTraceback attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace.module">module (mako.runtime.Namespace attribute)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="namespaces.html#mako.runtime.TemplateNamespace.module">(mako.runtime.TemplateNamespace attribute)</a>
+      </dt>
+    </dl></dd>
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.ModuleNamespace">ModuleNamespace (class in mako.runtime)</a>
+</dt>
+
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="N">N</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace">Namespace (class in mako.runtime)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="P">P</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="caching.html#mako.cache.CacheImpl.pass_context">pass_context (mako.cache.CacheImpl attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="runtime.html#mako.runtime.Context.pop_caller">pop_caller() (mako.runtime.Context method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="runtime.html#mako.runtime.Context.push_caller">push_caller() (mako.runtime.Context method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.put">put() (mako.cache.Cache method)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="usage.html#mako.lookup.TemplateLookup.put_string">put_string() (mako.lookup.TemplateLookup method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.lookup.TemplateLookup.put_template">put_template() (mako.lookup.TemplateLookup method)</a>
+</dt>
+
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="R">R</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="usage.html#RichTraceback.records">records (RichTraceback attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="caching.html#mako.cache.register_plugin">register_plugin() (in module mako.cache)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.template.Template.render">render() (mako.template.Template method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.template.Template.render_context">render_context() (mako.template.Template method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.template.Template.render_unicode">render_unicode() (mako.template.Template method)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="usage.html#RichTraceback.reverse_records">reverse_records (RichTraceback attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#RichTraceback.reverse_traceback">reverse_traceback (RichTraceback attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.exceptions.RichTraceback">RichTraceback (class in mako.exceptions)</a>
+</dt>
+
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="S">S</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.set">set() (mako.cache.Cache method)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="caching.html#mako.cache.CacheImpl.set">(mako.cache.CacheImpl method)</a>
+      </dt>
+    </dl></dd>
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.template.Template.source">source (mako.template.Template attribute)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="usage.html#RichTraceback.source">(RichTraceback attribute)</a>
+      </dt>
+    </dl></dd>
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="caching.html#mako.cache.Cache.starttime">starttime (mako.cache.Cache attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.supports_caller">supports_caller() (in module mako.runtime)</a>
+</dt>
+
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="T">T</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="usage.html#mako.template.Template">Template (class in mako.template)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace.template">template (mako.runtime.Namespace attribute)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.lookup.TemplateCollection">TemplateCollection (class in mako.lookup)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.lookup.TemplateLookup">TemplateLookup (class in mako.lookup)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.TemplateNamespace">TemplateNamespace (class in mako.runtime)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="usage.html#mako.exceptions.text_error_template">text_error_template() (in module mako.exceptions)</a>
+</dt>
+
+
+  
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="U">U</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="runtime.html#mako.runtime.Undefined">Undefined (class in mako.runtime)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="namespaces.html#mako.runtime.Namespace.uri">uri (mako.runtime.Namespace attribute)</a>
+</dt>
+
+    <dd><dl>
+      <dt><a href="namespaces.html#mako.runtime.TemplateNamespace.uri">(mako.runtime.TemplateNamespace attribute)</a>
+      </dt>
+    </dl></dd>
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+<dt></dt></dl>
+</td></tr></table>
+<h2 id="W">W</h2>
+<table width="100%" class="indextable genindextable"><tr><td width="33%" valign="top">
+<dl>
+    
+
+<dt>
+        <a href="runtime.html#mako.runtime.Context.write">write() (mako.runtime.Context method)</a>
+</dt>
+
+
+  
+
+
+<dt>
+        <a href="runtime.html#mako.runtime.Context.writer">writer() (mako.runtime.Context method)</a>
+</dt>
+
+
+  
+     
+        </dl></td><td width="33%" valign="top"><dl>
+
+<dt></dt></dl>
+</td></tr></table>
+
+
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/index.html b/lib3/Mako-0.7.3/doc/index.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/index.html
@@ -0,0 +1,230 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="#" />
+        <link rel="next" title="Usage" href="usage.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Next:
+            <a href="usage.html" title="next chapter">Usage</a>
+            </li>
+
+        <li>
+            <a href="#">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/index.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="#">Mako 0.7.3 Documentation</a>
+
+        <h2>
+            
+                Table of Contents
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+
+    <div id="docs-body" class="" >
+        
+<div class="section" id="table-of-contents">
+<h1>Table of Contents<a class="headerlink" href="#table-of-contents" title="Permalink to this headline">¶</a></h1>
+<div class="toctree-wrapper compound">
+<ul>
+<li class="toctree-l1"><a class="reference internal" href="usage.html">Usage</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#basic-usage">Basic Usage</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#using-file-based-templates">Using File-Based Templates</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#using-templatelookup">Using <tt class="docutils literal"><span class="pre">TemplateLookup</span></tt></a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#using-unicode-and-encoding">Using Unicode and Encoding</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#handling-exceptions">Handling Exceptions</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#common-framework-integrations">Common Framework Integrations</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#api-reference">API Reference</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="syntax.html">Syntax</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="syntax.html#expression-substitution">Expression Substitution</a></li>
+<li class="toctree-l2"><a class="reference internal" href="syntax.html#expression-escaping">Expression Escaping</a></li>
+<li class="toctree-l2"><a class="reference internal" href="syntax.html#control-structures">Control Structures</a></li>
+<li class="toctree-l2"><a class="reference internal" href="syntax.html#comments">Comments</a></li>
+<li class="toctree-l2"><a class="reference internal" href="syntax.html#newline-filters">Newline Filters</a></li>
+<li class="toctree-l2"><a class="reference internal" href="syntax.html#python-blocks">Python Blocks</a></li>
+<li class="toctree-l2"><a class="reference internal" href="syntax.html#module-level-blocks">Module-level Blocks</a></li>
+<li class="toctree-l2"><a class="reference internal" href="syntax.html#tags">Tags</a></li>
+<li class="toctree-l2"><a class="reference internal" href="syntax.html#returning-early-from-a-template">Returning Early from a Template</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="defs.html">Defs and Blocks</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="defs.html#using-defs">Using Defs</a></li>
+<li class="toctree-l2"><a class="reference internal" href="defs.html#using-blocks">Using Blocks</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="runtime.html">The Mako Runtime Environment</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="runtime.html#context">Context</a></li>
+<li class="toctree-l2"><a class="reference internal" href="runtime.html#the-loop-context">The Loop Context</a></li>
+<li class="toctree-l2"><a class="reference internal" href="runtime.html#all-the-built-in-names">All the Built-in Names</a></li>
+<li class="toctree-l2"><a class="reference internal" href="runtime.html#api-reference">API Reference</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="namespaces.html">Namespaces</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="namespaces.html#ways-to-call-namespaces">Ways to Call Namespaces</a></li>
+<li class="toctree-l2"><a class="reference internal" href="namespaces.html#namespaces-from-regular-python-modules">Namespaces from Regular Python Modules</a></li>
+<li class="toctree-l2"><a class="reference internal" href="namespaces.html#declaring-defs-in-namespaces">Declaring Defs in Namespaces</a></li>
+<li class="toctree-l2"><a class="reference internal" href="namespaces.html#the-body-method">The <tt class="docutils literal"><span class="pre">body()</span></tt> Method</a></li>
+<li class="toctree-l2"><a class="reference internal" href="namespaces.html#built-in-namespaces">Built-in Namespaces</a></li>
+<li class="toctree-l2"><a class="reference internal" href="namespaces.html#inheritable-namespaces">Inheritable Namespaces</a></li>
+<li class="toctree-l2"><a class="reference internal" href="namespaces.html#api-reference">API Reference</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="inheritance.html">Inheritance</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="inheritance.html#nesting-blocks">Nesting Blocks</a></li>
+<li class="toctree-l2"><a class="reference internal" href="inheritance.html#rendering-a-named-block-multiple-times">Rendering a Named Block Multiple Times</a></li>
+<li class="toctree-l2"><a class="reference internal" href="inheritance.html#but-what-about-defs">But what about Defs?</a></li>
+<li class="toctree-l2"><a class="reference internal" href="inheritance.html#using-the-next-namespace-to-produce-content-wrapping">Using the <tt class="docutils literal"><span class="pre">next</span></tt> Namespace to Produce Content Wrapping</a></li>
+<li class="toctree-l2"><a class="reference internal" href="inheritance.html#using-the-parent-namespace-to-augment-defs">Using the <tt class="docutils literal"><span class="pre">parent</span></tt> Namespace to Augment Defs</a></li>
+<li class="toctree-l2"><a class="reference internal" href="inheritance.html#inheritable-attributes">Inheritable Attributes</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="filtering.html">Filtering and Buffering</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="filtering.html#expression-filtering">Expression Filtering</a></li>
+<li class="toctree-l2"><a class="reference internal" href="filtering.html#filtering-defs-and-blocks">Filtering Defs and Blocks</a></li>
+<li class="toctree-l2"><a class="reference internal" href="filtering.html#buffering">Buffering</a></li>
+<li class="toctree-l2"><a class="reference internal" href="filtering.html#decorating">Decorating</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="unicode.html">The Unicode Chapter</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="unicode.html#specifying-the-encoding-of-a-template-file">Specifying the Encoding of a Template File</a></li>
+<li class="toctree-l2"><a class="reference internal" href="unicode.html#handling-expressions">Handling Expressions</a></li>
+<li class="toctree-l2"><a class="reference internal" href="unicode.html#defining-output-encoding">Defining Output Encoding</a></li>
+<li class="toctree-l2"><a class="reference internal" href="unicode.html#saying-to-heck-with-it-disabling-the-usage-of-unicode-entirely">Saying to Heck with It: Disabling the Usage of Unicode Entirely</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference internal" href="caching.html">Caching</a><ul>
+<li class="toctree-l2"><a class="reference internal" href="caching.html#cache-arguments">Cache Arguments</a></li>
+<li class="toctree-l2"><a class="reference internal" href="caching.html#programmatic-cache-access">Programmatic Cache Access</a></li>
+<li class="toctree-l2"><a class="reference internal" href="caching.html#cache-plugins">Cache Plugins</a></li>
+<li class="toctree-l2"><a class="reference internal" href="caching.html#api-reference">API Reference</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="indices-and-tables">
+<h2>Indices and Tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h2>
+<ul class="simple">
+<li><a class="reference internal" href="genindex.html"><em>Index</em></a></li>
+<li><a class="reference internal" href="search.html"><em>Search Page</em></a></li>
+</ul>
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Next:
+        <a href="usage.html" title="next chapter">Usage</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/inheritance.html b/lib3/Mako-0.7.3/doc/inheritance.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/inheritance.html
@@ -0,0 +1,673 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+                Inheritance
+             — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+        <link rel="next" title="Filtering and Buffering" href="filtering.html" />
+        <link rel="prev" title="Namespaces" href="namespaces.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Prev:
+            <a href="namespaces.html" title="previous chapter">Namespaces</a>
+            </li>
+            <li>Next:
+            <a href="filtering.html" title="next chapter">Filtering and Buffering</a>
+            </li>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/inheritance.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+                Inheritance
+             
+
+        <h2>
+            
+                Inheritance
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+    <div id="docs-sidebar">
+    <h3><a href="index.html">Table of Contents</a></h3>
+    <ul>
+<li><a class="reference internal" href="#">Inheritance</a><ul>
+<li><a class="reference internal" href="#nesting-blocks">Nesting Blocks</a></li>
+<li><a class="reference internal" href="#rendering-a-named-block-multiple-times">Rendering a Named Block Multiple Times</a></li>
+<li><a class="reference internal" href="#but-what-about-defs">But what about Defs?</a></li>
+<li><a class="reference internal" href="#using-the-next-namespace-to-produce-content-wrapping">Using the <tt class="docutils literal"><span class="pre">next</span></tt> Namespace to Produce Content Wrapping</a></li>
+<li><a class="reference internal" href="#using-the-parent-namespace-to-augment-defs">Using the <tt class="docutils literal"><span class="pre">parent</span></tt> Namespace to Augment Defs</a></li>
+<li><a class="reference internal" href="#inheritable-attributes">Inheritable Attributes</a></li>
+</ul>
+</li>
+</ul>
+
+
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="namespaces.html" title="previous chapter">Namespaces</a>
+    </p>
+    <h4>Next Topic</h4>
+    <p>
+    <a href="filtering.html" title="next chapter">Filtering and Buffering</a>
+    </p>
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+
+    <div id="docs-body" class="withsidebar" >
+        
+<div class="section" id="inheritance">
+<span id="inheritance-toplevel"></span><h1>Inheritance<a class="headerlink" href="#inheritance" title="Permalink to this headline">¶</a></h1>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Most of the inheritance examples here take advantage of a feature that’s
+new in Mako as of version 0.4.1 called the “block”.  This tag is very similar to
+the “def” tag but is more streamlined for usage with inheritance.  Note that
+all of the examples here which use blocks can also use defs instead.  Contrasting
+usages will be illustrated.</p>
+</div>
+<p>Using template inheritance, two or more templates can organize
+themselves into an <strong>inheritance chain</strong>, where content and
+functions from all involved templates can be intermixed. The
+general paradigm of template inheritance is this: if a template
+<tt class="docutils literal"><span class="pre">A</span></tt> inherits from template <tt class="docutils literal"><span class="pre">B</span></tt>, then template <tt class="docutils literal"><span class="pre">A</span></tt> agrees
+to send the executional control to template <tt class="docutils literal"><span class="pre">B</span></tt> at runtime
+(<tt class="docutils literal"><span class="pre">A</span></tt> is called the <strong>inheriting</strong> template). Template <tt class="docutils literal"><span class="pre">B</span></tt>,
+the <strong>inherited</strong> template, then makes decisions as to what
+resources from <tt class="docutils literal"><span class="pre">A</span></tt> shall be executed.</p>
+<p>In practice, it looks like this. Here’s a hypothetical inheriting
+template, <tt class="docutils literal"><span class="pre">index.html</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## index.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"base.html"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is some header content</span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+
+<span class="x">this is the body content.</span>
+</pre></div>
+</div>
+<p>And <tt class="docutils literal"><span class="pre">base.html</span></tt>, the inherited template:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## base.html</span><span class="x"></span>
+<span class="x"><html></span>
+<span class="x">    <body></span>
+<span class="x">        <div class="header"></span>
+<span class="x">            </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">/></span><span class="x"></span>
+<span class="x">        </div></span>
+
+<span class="x">        </span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+
+<span class="x">        <div class="footer"></span>
+<span class="x">            </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"footer"</span><span class="cp">></span><span class="x"></span>
+<span class="x">                this is the footer</span>
+<span class="x">            </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">        </div></span>
+<span class="x">    </body></span>
+<span class="x"></html></span>
+</pre></div>
+</div>
+<p>Here is a breakdown of the execution:</p>
+<ol class="arabic">
+<li><p class="first">When <tt class="docutils literal"><span class="pre">index.html</span></tt> is rendered, control immediately passes to
+<tt class="docutils literal"><span class="pre">base.html</span></tt>.</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">base.html</span></tt> then renders the top part of an HTML document,
+then invokes the <tt class="docutils literal"><span class="pre"><%block</span> <span class="pre">name="header"></span></tt> block.  It invokes the
+underlying <tt class="docutils literal"><span class="pre">header()</span></tt> function off of a built-in namespace
+called <tt class="docutils literal"><span class="pre">self</span></tt> (this namespace was first introduced in the
+<a class="reference internal" href="namespaces.html"><em>Namespaces chapter</em></a> in <a class="reference internal" href="namespaces.html#namespace-self"><em>self</em></a>). Since
+<tt class="docutils literal"><span class="pre">index.html</span></tt> is the topmost template and also defines a block
+called <tt class="docutils literal"><span class="pre">header</span></tt>, it’s this <tt class="docutils literal"><span class="pre">header</span></tt> block that ultimately gets
+executed – instead of the one that’s present in <tt class="docutils literal"><span class="pre">base.html</span></tt>.</p>
+</li>
+<li><p class="first">Control comes back to <tt class="docutils literal"><span class="pre">base.html</span></tt>. Some more HTML is
+rendered.</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">base.html</span></tt> executes <tt class="docutils literal"><span class="pre">self.body()</span></tt>. The <tt class="docutils literal"><span class="pre">body()</span></tt>
+function on all template-based namespaces refers to the main
+body of the template, therefore the main body of
+<tt class="docutils literal"><span class="pre">index.html</span></tt> is rendered.</p>
+</li>
+<li><p class="first">When <tt class="docutils literal"><span class="pre"><%block</span> <span class="pre">name="header"></span></tt> is encountered in <tt class="docutils literal"><span class="pre">index.html</span></tt>
+during the <tt class="docutils literal"><span class="pre">self.body()</span></tt> call, a conditional is checked – does the
+current inherited template, i.e. <tt class="docutils literal"><span class="pre">base.html</span></tt>, also define this block? If yes,
+the <tt class="docutils literal"><span class="pre"><%block></span></tt> is <strong>not</strong> executed here – the inheritance
+mechanism knows that the parent template is responsible for rendering
+this block (and in fact it already has).  In other words a block
+only renders in its <em>basemost scope</em>.</p>
+</li>
+<li><p class="first">Control comes back to <tt class="docutils literal"><span class="pre">base.html</span></tt>. More HTML is rendered,
+then the <tt class="docutils literal"><span class="pre"><%block</span> <span class="pre">name="footer"></span></tt> expression is invoked.</p>
+</li>
+<li><p class="first">The <tt class="docutils literal"><span class="pre">footer</span></tt> block is only defined in <tt class="docutils literal"><span class="pre">base.html</span></tt>, so being
+the topmost definition of <tt class="docutils literal"><span class="pre">footer</span></tt>, it’s the one that
+executes. If <tt class="docutils literal"><span class="pre">index.html</span></tt> also specified <tt class="docutils literal"><span class="pre">footer</span></tt>, then
+its version would <strong>override</strong> that of the base.</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">base.html</span></tt> finishes up rendering its HTML and the template
+is complete, producing:</p>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><html></span>
+    <span class="nt"><body></span>
+        <span class="nt"><div</span> <span class="na">class=</span><span class="s">"header"</span><span class="nt">></span>
+            this is some header content
+        <span class="nt"></div></span>
+
+        this is the body content.
+
+        <span class="nt"><div</span> <span class="na">class=</span><span class="s">"footer"</span><span class="nt">></span>
+            this is the footer
+        <span class="nt"></div></span>
+    <span class="nt"></body></span>
+<span class="nt"></html></span>
+</pre></div>
+</div>
+</li>
+</ol>
+<p>...and that is template inheritance in a nutshell. The main idea
+is that the methods that you call upon <tt class="docutils literal"><span class="pre">self</span></tt> always
+correspond to the topmost definition of that method. Very much
+the way <tt class="docutils literal"><span class="pre">self</span></tt> works in a Python class, even though Mako is
+not actually using Python class inheritance to implement this
+functionality. (Mako doesn’t take the “inheritance” metaphor too
+seriously; while useful to setup some commonly recognized
+semantics, a textual template is not very much like an
+object-oriented class construct in practice).</p>
+<div class="section" id="nesting-blocks">
+<h2>Nesting Blocks<a class="headerlink" href="#nesting-blocks" title="Permalink to this headline">¶</a></h2>
+<p>The named blocks defined in an inherited template can also be nested within
+other blocks.  The name given to each block is globally accessible via any inheriting
+template.  We can add a new block <tt class="docutils literal"><span class="pre">title</span></tt> to our <tt class="docutils literal"><span class="pre">header</span></tt> block:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## base.html</span><span class="x"></span>
+<span class="x"><html></span>
+<span class="x">    <body></span>
+<span class="x">        <div class="header"></span>
+<span class="x">            </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">></span><span class="x"></span>
+<span class="x">                <h2></span>
+<span class="x">                    </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"title"</span><span class="cp">/></span><span class="x"></span>
+<span class="x">                </h2></span>
+<span class="x">            </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">        </div></span>
+
+<span class="x">        </span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+
+<span class="x">        <div class="footer"></span>
+<span class="x">            </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"footer"</span><span class="cp">></span><span class="x"></span>
+<span class="x">                this is the footer</span>
+<span class="x">            </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">        </div></span>
+<span class="x">    </body></span>
+<span class="x"></html></span>
+</pre></div>
+</div>
+<p>The inheriting template can name either or both of <tt class="docutils literal"><span class="pre">header</span></tt> and <tt class="docutils literal"><span class="pre">title</span></tt>, separately
+or nested themselves:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## index.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"base.html"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is some header content</span>
+<span class="x">    </span><span class="cp">${</span><span class="n">parent</span><span class="o">.</span><span class="n">header</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"title"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is the title</span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+
+<span class="x">this is the body content.</span>
+</pre></div>
+</div>
+<p>Note when we overrode <tt class="docutils literal"><span class="pre">header</span></tt>, we added an extra call <tt class="docutils literal"><span class="pre">${parent.header()}</span></tt> in order to invoke
+the parent’s <tt class="docutils literal"><span class="pre">header</span></tt> block in addition to our own.  That’s described in more detail below,
+in <a class="reference internal" href="#parent-namespace"><em>Using the parent Namespace to Augment Defs</em></a>.</p>
+</div>
+<div class="section" id="rendering-a-named-block-multiple-times">
+<h2>Rendering a Named Block Multiple Times<a class="headerlink" href="#rendering-a-named-block-multiple-times" title="Permalink to this headline">¶</a></h2>
+<p>Recall from the section <a class="reference internal" href="defs.html#blocks"><em>Using Blocks</em></a> that a named block is just like a <tt class="docutils literal"><span class="pre"><%def></span></tt>,
+with some different usage rules.  We can call one of our named sections distinctly, for example
+a section that is used more than once, such as the title of a page:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><html></span>
+<span class="x">    <head></span>
+<span class="x">        <title></span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">()</span><span class="cp">}</span><span class="x"></title></span>
+<span class="x">    </head></span>
+<span class="x">    <body></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        <h2></span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"title"</span><span class="cp">/></span><span class="x"></h2></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">    </body></span>
+<span class="x"></html></span>
+</pre></div>
+</div>
+<p>Where above an inheriting template can define <tt class="docutils literal"><span class="pre"><%block</span> <span class="pre">name="title"></span></tt> just once, and it will be
+used in the base template both in the <tt class="docutils literal"><span class="pre"><title></span></tt> section as well as the <tt class="docutils literal"><span class="pre"><h2></span></tt>.</p>
+</div>
+<div class="section" id="but-what-about-defs">
+<h2>But what about Defs?<a class="headerlink" href="#but-what-about-defs" title="Permalink to this headline">¶</a></h2>
+<p>The previous example used the <tt class="docutils literal"><span class="pre"><%block></span></tt> tag to produce areas of content
+to be overridden.  Before Mako 0.4.1, there wasn’t any such tag – instead
+there was only the <tt class="docutils literal"><span class="pre"><%def></span></tt> tag.   As it turns out, named blocks and defs are
+largely interchangeable.  The def simply doesn’t call itself automatically,
+and has more open-ended naming and scoping rules that are more flexible and similar
+to Python itself, but less suited towards layout.  The first example from
+this chapter using defs would look like:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## index.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"base.html"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"header()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is some header content</span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="x">this is the body content.</span>
+</pre></div>
+</div>
+<p>And <tt class="docutils literal"><span class="pre">base.html</span></tt>, the inherited template:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## base.html</span><span class="x"></span>
+<span class="x"><html></span>
+<span class="x">    <body></span>
+<span class="x">        <div class="header"></span>
+<span class="x">            </span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">header</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">        </div></span>
+
+<span class="x">        </span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+
+<span class="x">        <div class="footer"></span>
+<span class="x">            </span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">footer</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">        </div></span>
+<span class="x">    </body></span>
+<span class="x"></html></span>
+
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"header()"</span><span class="cp">/></span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"footer()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is the footer</span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Above, we illustrate that defs differ from blocks in that their definition
+and invocation are defined in two separate places, instead of at once. You can <em>almost</em> do exactly what a
+block does if you put the two together:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><div class="header"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"header()"</span><span class="cp">></%</span><span class="nb">def</span><span class="cp">>${</span><span class="bp">self</span><span class="o">.</span><span class="n">header</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x"></div></span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre"><%block></span></tt> is obviously more streamlined than the <tt class="docutils literal"><span class="pre"><%def></span></tt> for this kind
+of usage.  In addition,
+the above “inline” approach with <tt class="docutils literal"><span class="pre"><%def></span></tt> does not work with nesting:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><head></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"header()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        <title></span>
+<span class="x">        ## this won't work !</span>
+<span class="x">        </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"title()"</span><span class="cp">></span><span class="x">default title</span><span class="cp"></%</span><span class="nb">def</span><span class="cp">>${</span><span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">        </title></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">def</span><span class="cp">>${</span><span class="bp">self</span><span class="o">.</span><span class="n">header</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x"></head></span>
+</pre></div>
+</div>
+<p>Where above, the <tt class="docutils literal"><span class="pre">title()</span></tt> def, because it’s a def within a def, is not part of the
+template’s exported namespace and will not be part of <tt class="docutils literal"><span class="pre">self</span></tt>.  If the inherited template
+did define its own <tt class="docutils literal"><span class="pre">title</span></tt> def at the top level, it would be called, but the “default title”
+above is not present at all on <tt class="docutils literal"><span class="pre">self</span></tt> no matter what.  For this to work as expected
+you’d instead need to say:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><head></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"header()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        <title></span>
+<span class="x">        </span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">        </title></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">def</span><span class="cp">>${</span><span class="bp">self</span><span class="o">.</span><span class="n">header</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"title()"</span><span class="cp">/></span><span class="x"></span>
+<span class="x"></head></span>
+</pre></div>
+</div>
+<p>That is, <tt class="docutils literal"><span class="pre">title</span></tt> is defined outside of any other defs so that it is in the <tt class="docutils literal"><span class="pre">self</span></tt> namespace.
+It works, but the definition needs to be potentially far away from the point of render.</p>
+<p>A named block is always placed in the <tt class="docutils literal"><span class="pre">self</span></tt> namespace, regardless of nesting,
+so this restriction is lifted:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## base.html</span><span class="x"></span>
+<span class="x"><head></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        <title></span>
+<span class="x">        </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"title"</span><span class="cp">/></span><span class="x"></span>
+<span class="x">        </title></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x"></head></span>
+</pre></div>
+</div>
+<p>The above template defines <tt class="docutils literal"><span class="pre">title</span></tt> inside of <tt class="docutils literal"><span class="pre">header</span></tt>, and an inheriting template can define
+one or both in <strong>any</strong> configuration, nested inside each other or not, in order for them to be used:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## index.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"base.html"</span><span class="cp">/></span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"title"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    the title</span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    the header</span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>So while the <tt class="docutils literal"><span class="pre"><%block></span></tt> tag lifts the restriction of nested blocks not being available externally,
+in order to achieve this it <em>adds</em> the restriction that all block names in a single template need
+to be globally unique within the template, and additionally that a <tt class="docutils literal"><span class="pre"><%block></span></tt> can’t be defined
+inside of a <tt class="docutils literal"><span class="pre"><%def></span></tt>. It’s a more restricted tag suited towards a more specific use case than <tt class="docutils literal"><span class="pre"><%def></span></tt>.</p>
+</div>
+<div class="section" id="using-the-next-namespace-to-produce-content-wrapping">
+<h2>Using the <tt class="docutils literal"><span class="pre">next</span></tt> Namespace to Produce Content Wrapping<a class="headerlink" href="#using-the-next-namespace-to-produce-content-wrapping" title="Permalink to this headline">¶</a></h2>
+<p>Sometimes you have an inheritance chain that spans more than two
+templates. Or maybe you don’t, but you’d like to build your
+system such that extra inherited templates can be inserted in
+the middle of a chain where they would be smoothly integrated.
+If each template wants to define its layout just within its main
+body, you can’t just call <tt class="docutils literal"><span class="pre">self.body()</span></tt> to get at the
+inheriting template’s body, since that is only the topmost body.
+To get at the body of the <em>next</em> template, you call upon the
+namespace <tt class="docutils literal"><span class="pre">next</span></tt>, which is the namespace of the template
+<strong>immediately following</strong> the current template.</p>
+<p>Lets change the line in <tt class="docutils literal"><span class="pre">base.html</span></tt> which calls upon
+<tt class="docutils literal"><span class="pre">self.body()</span></tt> to instead call upon <tt class="docutils literal"><span class="pre">next.body()</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## base.html</span><span class="x"></span>
+<span class="x"><html></span>
+<span class="x">    <body></span>
+<span class="x">        <div class="header"></span>
+<span class="x">            </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">/></span><span class="x"></span>
+<span class="x">        </div></span>
+
+<span class="x">        </span><span class="cp">${</span><span class="nb">next</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+
+<span class="x">        <div class="footer"></span>
+<span class="x">            </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"footer"</span><span class="cp">></span><span class="x"></span>
+<span class="x">                this is the footer</span>
+<span class="x">            </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">        </div></span>
+<span class="x">    </body></span>
+<span class="x"></html></span>
+</pre></div>
+</div>
+<p>Lets also add an intermediate template called <tt class="docutils literal"><span class="pre">layout.html</span></tt>,
+which inherits from <tt class="docutils literal"><span class="pre">base.html</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## layout.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"base.html"</span><span class="cp">/></span><span class="x"></span>
+<span class="x"><ul></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"toolbar"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        <li>selection 1</li></span>
+<span class="x">        <li>selection 2</li></span>
+<span class="x">        <li>selection 3</li></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x"></ul></span>
+<span class="x"><div class="mainlayout"></span>
+<span class="x">    </span><span class="cp">${</span><span class="nb">next</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x"></div></span>
+</pre></div>
+</div>
+<p>And finally change <tt class="docutils literal"><span class="pre">index.html</span></tt> to inherit from
+<tt class="docutils literal"><span class="pre">layout.html</span></tt> instead:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## index.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"layout.html"</span><span class="cp">/></span>
+
+<span class="cp">## .. rest of template</span><span class="x"></span>
+</pre></div>
+</div>
+<p>In this setup, each call to <tt class="docutils literal"><span class="pre">next.body()</span></tt> will render the body
+of the next template in the inheritance chain (which can be
+written as <tt class="docutils literal"><span class="pre">base.html</span> <span class="pre">-></span> <span class="pre">layout.html</span> <span class="pre">-></span> <span class="pre">index.html</span></tt>). Control
+is still first passed to the bottommost template <tt class="docutils literal"><span class="pre">base.html</span></tt>,
+and <tt class="docutils literal"><span class="pre">self</span></tt> still references the topmost definition of any
+particular def.</p>
+<p>The output we get would be:</p>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><html></span>
+    <span class="nt"><body></span>
+        <span class="nt"><div</span> <span class="na">class=</span><span class="s">"header"</span><span class="nt">></span>
+            this is some header content
+        <span class="nt"></div></span>
+
+        <span class="nt"><ul></span>
+            <span class="nt"><li></span>selection 1<span class="nt"></li></span>
+            <span class="nt"><li></span>selection 2<span class="nt"></li></span>
+            <span class="nt"><li></span>selection 3<span class="nt"></li></span>
+        <span class="nt"></ul></span>
+
+        <span class="nt"><div</span> <span class="na">class=</span><span class="s">"mainlayout"</span><span class="nt">></span>
+        this is the body content.
+        <span class="nt"></div></span>
+
+        <span class="nt"><div</span> <span class="na">class=</span><span class="s">"footer"</span><span class="nt">></span>
+            this is the footer
+        <span class="nt"></div></span>
+    <span class="nt"></body></span>
+<span class="nt"></html></span>
+</pre></div>
+</div>
+<p>So above, we have the <tt class="docutils literal"><span class="pre"><html></span></tt>, <tt class="docutils literal"><span class="pre"><body></span></tt> and
+<tt class="docutils literal"><span class="pre">header</span></tt>/<tt class="docutils literal"><span class="pre">footer</span></tt> layout of <tt class="docutils literal"><span class="pre">base.html</span></tt>, we have the
+<tt class="docutils literal"><span class="pre"><ul></span></tt> and <tt class="docutils literal"><span class="pre">mainlayout</span></tt> section of <tt class="docutils literal"><span class="pre">layout.html</span></tt>, and the
+main body of <tt class="docutils literal"><span class="pre">index.html</span></tt> as well as its overridden <tt class="docutils literal"><span class="pre">header</span></tt>
+def. The <tt class="docutils literal"><span class="pre">layout.html</span></tt> template is inserted into the middle of
+the chain without <tt class="docutils literal"><span class="pre">base.html</span></tt> having to change anything.
+Without the <tt class="docutils literal"><span class="pre">next</span></tt> namespace, only the main body of
+<tt class="docutils literal"><span class="pre">index.html</span></tt> could be used; there would be no way to call
+<tt class="docutils literal"><span class="pre">layout.html</span></tt>‘s body content.</p>
+</div>
+<div class="section" id="using-the-parent-namespace-to-augment-defs">
+<span id="parent-namespace"></span><h2>Using the <tt class="docutils literal"><span class="pre">parent</span></tt> Namespace to Augment Defs<a class="headerlink" href="#using-the-parent-namespace-to-augment-defs" title="Permalink to this headline">¶</a></h2>
+<p>Lets now look at the other inheritance-specific namespace, the
+opposite of <tt class="docutils literal"><span class="pre">next</span></tt> called <tt class="docutils literal"><span class="pre">parent</span></tt>. <tt class="docutils literal"><span class="pre">parent</span></tt> is the
+namespace of the template <strong>immediately preceding</strong> the current
+template. What’s useful about this namespace is that
+defs or blocks can call upon their overridden versions.
+This is not as hard as it sounds and
+is very much like using the <tt class="docutils literal"><span class="pre">super</span></tt> keyword in Python. Lets
+modify <tt class="docutils literal"><span class="pre">index.html</span></tt> to augment the list of selections provided
+by the <tt class="docutils literal"><span class="pre">toolbar</span></tt> function in <tt class="docutils literal"><span class="pre">layout.html</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## index.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"layout.html"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is some header content</span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"toolbar"</span><span class="cp">></span>
+    <span class="cp">## call the parent's toolbar first</span><span class="x"></span>
+<span class="x">    </span><span class="cp">${</span><span class="n">parent</span><span class="o">.</span><span class="n">toolbar</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">    <li>selection 4</li></span>
+<span class="x">    <li>selection 5</li></span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+
+<span class="x">this is the body content.</span>
+</pre></div>
+</div>
+<p>Above, we implemented a <tt class="docutils literal"><span class="pre">toolbar()</span></tt> function, which is meant
+to override the definition of <tt class="docutils literal"><span class="pre">toolbar</span></tt> within the inherited
+template <tt class="docutils literal"><span class="pre">layout.html</span></tt>. However, since we want the content
+from that of <tt class="docutils literal"><span class="pre">layout.html</span></tt> as well, we call it via the
+<tt class="docutils literal"><span class="pre">parent</span></tt> namespace whenever we want it’s content, in this case
+before we add our own selections. So the output for the whole
+thing is now:</p>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><html></span>
+    <span class="nt"><body></span>
+        <span class="nt"><div</span> <span class="na">class=</span><span class="s">"header"</span><span class="nt">></span>
+            this is some header content
+        <span class="nt"></div></span>
+
+        <span class="nt"><ul></span>
+            <span class="nt"><li></span>selection 1<span class="nt"></li></span>
+            <span class="nt"><li></span>selection 2<span class="nt"></li></span>
+            <span class="nt"><li></span>selection 3<span class="nt"></li></span>
+            <span class="nt"><li></span>selection 4<span class="nt"></li></span>
+            <span class="nt"><li></span>selection 5<span class="nt"></li></span>
+        <span class="nt"></ul></span>
+
+        <span class="nt"><div</span> <span class="na">class=</span><span class="s">"mainlayout"</span><span class="nt">></span>
+        this is the body content.
+        <span class="nt"></div></span>
+
+        <span class="nt"><div</span> <span class="na">class=</span><span class="s">"footer"</span><span class="nt">></span>
+            this is the footer
+        <span class="nt"></div></span>
+    <span class="nt"></body></span>
+<span class="nt"></html></span>
+</pre></div>
+</div>
+<p>and you’re now a template inheritance ninja!</p>
+</div>
+<div class="section" id="inheritable-attributes">
+<h2>Inheritable Attributes<a class="headerlink" href="#inheritable-attributes" title="Permalink to this headline">¶</a></h2>
+<p>The <a class="reference internal" href="namespaces.html#mako.runtime.Namespace.attr" title="mako.runtime.Namespace.attr"><tt class="xref py py-attr docutils literal"><span class="pre">attr</span></tt></a> accessor of the <a class="reference internal" href="namespaces.html#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a> object
+allows access to module level variables declared in a template. By accessing
+<tt class="docutils literal"><span class="pre">self.attr</span></tt>, you can access regular attributes from the
+inheritance chain as declared in <tt class="docutils literal"><span class="pre"><%!</span> <span class="pre">%></span></tt> sections. Such as:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%!</span>
+    <span class="n">class_</span> <span class="o">=</span> <span class="s">"grey"</span>
+<span class="cp">%></span><span class="x"></span>
+
+<span class="x"><div class="</span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">attr</span><span class="o">.</span><span class="n">class_</span><span class="cp">}</span><span class="x">"></span>
+<span class="x">    </span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x"></div></span>
+</pre></div>
+</div>
+<p>If an inheriting template overrides <tt class="docutils literal"><span class="pre">class_</span></tt> to be
+<tt class="docutils literal"><span class="pre">"white"</span></tt>, as in:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%!</span>
+    <span class="n">class_</span> <span class="o">=</span> <span class="s">"white"</span>
+<span class="cp">%></span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"parent.html"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="x">This is the body</span>
+</pre></div>
+</div>
+<p>you’ll get output like:</p>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><div</span> <span class="na">class=</span><span class="s">"white"</span><span class="nt">></span>
+    This is the body
+<span class="nt"></div></span>
+</pre></div>
+</div>
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Previous:
+        <a href="namespaces.html" title="previous chapter">Namespaces</a>
+        Next:
+        <a href="filtering.html" title="next chapter">Filtering and Buffering</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/namespaces.html b/lib3/Mako-0.7.3/doc/namespaces.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/namespaces.html
@@ -0,0 +1,649 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+                Namespaces
+             — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+        <link rel="next" title="Inheritance" href="inheritance.html" />
+        <link rel="prev" title="The Mako Runtime Environment" href="runtime.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Prev:
+            <a href="runtime.html" title="previous chapter">The Mako Runtime Environment</a>
+            </li>
+            <li>Next:
+            <a href="inheritance.html" title="next chapter">Inheritance</a>
+            </li>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/namespaces.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+                Namespaces
+             
+
+        <h2>
+            
+                Namespaces
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+    <div id="docs-sidebar">
+    <h3><a href="index.html">Table of Contents</a></h3>
+    <ul>
+<li><a class="reference internal" href="#">Namespaces</a><ul>
+<li><a class="reference internal" href="#ways-to-call-namespaces">Ways to Call Namespaces</a></li>
+<li><a class="reference internal" href="#namespaces-from-regular-python-modules">Namespaces from Regular Python Modules</a></li>
+<li><a class="reference internal" href="#declaring-defs-in-namespaces">Declaring Defs in Namespaces</a></li>
+<li><a class="reference internal" href="#the-body-method">The <tt class="docutils literal"><span class="pre">body()</span></tt> Method</a></li>
+<li><a class="reference internal" href="#built-in-namespaces">Built-in Namespaces</a><ul>
+<li><a class="reference internal" href="#local"><tt class="docutils literal"><span class="pre">local</span></tt></a></li>
+<li><a class="reference internal" href="#self"><tt class="docutils literal"><span class="pre">self</span></tt></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#inheritable-namespaces">Inheritable Namespaces</a></li>
+<li><a class="reference internal" href="#api-reference">API Reference</a></li>
+</ul>
+</li>
+</ul>
+
+
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="runtime.html" title="previous chapter">The Mako Runtime Environment</a>
+    </p>
+    <h4>Next Topic</h4>
+    <p>
+    <a href="inheritance.html" title="next chapter">Inheritance</a>
+    </p>
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+
+    <div id="docs-body" class="withsidebar" >
+        
+<div class="section" id="namespaces">
+<span id="namespaces-toplevel"></span><h1>Namespaces<a class="headerlink" href="#namespaces" title="Permalink to this headline">¶</a></h1>
+<p>Namespaces are used to organize groups of defs into
+categories, and also to “import” defs from other files.</p>
+<p>If the file <tt class="docutils literal"><span class="pre">components.html</span></tt> defines these two defs:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## components.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"comp1()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is comp1</span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"comp2(x)"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is comp2, x is </span><span class="cp">${</span><span class="n">x</span><span class="cp">}</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>you can make another file, for example <tt class="docutils literal"><span class="pre">index.html</span></tt>, that
+pulls those two defs into a namespace called <tt class="docutils literal"><span class="pre">comp</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## index.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">namespace</span> <span class="na">name=</span><span class="s">"comp"</span> <span class="na">file=</span><span class="s">"components.html"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="x">Here's comp1:  </span><span class="cp">${</span><span class="n">comp</span><span class="o">.</span><span class="n">comp1</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">Here's comp2:  </span><span class="cp">${</span><span class="n">comp</span><span class="o">.</span><span class="n">comp2</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre">comp</span></tt> variable above is an instance of
+<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>, a <strong>proxy object</strong> which delivers
+method calls to the underlying template callable using the
+current context.</p>
+<p><tt class="docutils literal"><span class="pre"><%namespace></span></tt> also provides an <tt class="docutils literal"><span class="pre">import</span></tt> attribute which can
+be used to pull the names into the local namespace, removing the
+need to call it via the “<tt class="docutils literal"><span class="pre">.</span></tt>” operator. When <tt class="docutils literal"><span class="pre">import</span></tt> is used, the
+<tt class="docutils literal"><span class="pre">name</span></tt> attribute is optional.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">namespace</span> <span class="na">file=</span><span class="s">"components.html"</span> <span class="na">import=</span><span class="s">"comp1, comp2"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="x">Heres comp1:  </span><span class="cp">${</span><span class="n">comp1</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">Heres comp2:  </span><span class="cp">${</span><span class="n">comp2</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p><tt class="docutils literal"><span class="pre">import</span></tt> also supports the “<tt class="docutils literal"><span class="pre">*</span></tt>” operator:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">namespace</span> <span class="na">file=</span><span class="s">"components.html"</span> <span class="na">import=</span><span class="s">"*"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="x">Heres comp1:  </span><span class="cp">${</span><span class="n">comp1</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">Heres comp2:  </span><span class="cp">${</span><span class="n">comp2</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The names imported by the <tt class="docutils literal"><span class="pre">import</span></tt> attribute take precedence
+over any names that exist within the current context.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">In current versions of Mako, usage of <tt class="docutils literal"><span class="pre">import='*'</span></tt> is
+known to decrease performance of the template. This will be
+fixed in a future release.</p>
+</div>
+<p>The <tt class="docutils literal"><span class="pre">file</span></tt> argument allows expressions – if looking for
+context variables, the <tt class="docutils literal"><span class="pre">context</span></tt> must be named explicitly:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">namespace</span> <span class="na">name=</span><span class="s">"dyn"</span> <span class="na">file=</span><span class="s">"${context['namespace_name']}"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<div class="section" id="ways-to-call-namespaces">
+<h2>Ways to Call Namespaces<a class="headerlink" href="#ways-to-call-namespaces" title="Permalink to this headline">¶</a></h2>
+<p>There are essentially four ways to call a function from a
+namespace.</p>
+<p>The “expression” format, as described previously. Namespaces are
+just Python objects with functions on them, and can be used in
+expressions like any other function:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="n">mynamespace</span><span class="o">.</span><span class="n">somefunction</span><span class="p">(</span><span class="s">'some arg1'</span><span class="p">,</span> <span class="s">'some arg2'</span><span class="p">,</span> <span class="n">arg3</span><span class="o">=</span><span class="s">'some arg3'</span><span class="p">,</span> <span class="n">arg4</span><span class="o">=</span><span class="s">'some arg4'</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Synonymous with the “expression” format is the “custom tag”
+format, when a “closed” tag is used. This format, introduced in
+Mako 0.2.3, allows the usage of a “custom” Mako tag, with the
+function arguments passed in using named attributes:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">mynamespace:somefunction</span> <span class="na">arg1=</span><span class="s">"some arg1"</span> <span class="na">arg2=</span><span class="s">"some arg2"</span> <span class="na">arg3=</span><span class="s">"some arg3"</span> <span class="na">arg4=</span><span class="s">"some arg4"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>When using tags, the values of the arguments are taken as
+literal strings by default. To embed Python expressions as
+arguments, use the embedded expression format:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">mynamespace:somefunction</span> <span class="na">arg1=</span><span class="s">"${someobject.format()}"</span> <span class="na">arg2=</span><span class="s">"${somedef(5, 12)}"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The “custom tag” format is intended mainly for namespace
+functions which recognize body content, which in Mako is known
+as a “def with embedded content”:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">mynamespace:somefunction</span> <span class="na">arg1=</span><span class="s">"some argument"</span> <span class="na">args=</span><span class="s">"x, y"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    Some record: </span><span class="cp">${</span><span class="n">x</span><span class="cp">}</span><span class="x">, </span><span class="cp">${</span><span class="n">y</span><span class="cp">}</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">mynamespace:somefunction</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The “classic” way to call defs with embedded content is the <tt class="docutils literal"><span class="pre"><%call></span></tt> tag:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">call</span> <span class="na">expr=</span><span class="s">"mynamespace.somefunction(arg1='some argument')"</span> <span class="na">args=</span><span class="s">"x, y"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    Some record: </span><span class="cp">${</span><span class="n">x</span><span class="cp">}</span><span class="x">, </span><span class="cp">${</span><span class="n">y</span><span class="cp">}</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">call</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>For information on how to construct defs that embed content from
+the caller, see <a class="reference internal" href="defs.html#defs-with-content"><em>Calling a Def with Embedded Content and/or Other Defs</em></a>.</p>
+</div>
+<div class="section" id="namespaces-from-regular-python-modules">
+<span id="namespaces-python-modules"></span><h2>Namespaces from Regular Python Modules<a class="headerlink" href="#namespaces-from-regular-python-modules" title="Permalink to this headline">¶</a></h2>
+<p>Namespaces can also import regular Python functions from
+modules. These callables need to take at least one argument,
+<tt class="docutils literal"><span class="pre">context</span></tt>, an instance of <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>. A module file
+<tt class="docutils literal"><span class="pre">some/module.py</span></tt> might contain the callable:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">my_tag</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
+    <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"hello world"</span><span class="p">)</span>
+    <span class="k">return</span> <span class="s">''</span>
+</pre></div>
+</div>
+<p>A template can use this module via:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">namespace</span> <span class="na">name=</span><span class="s">"hw"</span> <span class="na">module=</span><span class="s">"some.module"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="cp">${</span><span class="n">hw</span><span class="o">.</span><span class="n">my_tag</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Note that the <tt class="docutils literal"><span class="pre">context</span></tt> argument is not needed in the call;
+the <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a> tag creates a locally-scoped callable which
+takes care of it. The <tt class="docutils literal"><span class="pre">return</span> <span class="pre">''</span></tt> is so that the def does not
+dump a <tt class="docutils literal"><span class="pre">None</span></tt> into the output stream – the return value of any
+def is rendered after the def completes, in addition to whatever
+was passed to <a class="reference internal" href="runtime.html#mako.runtime.Context.write" title="mako.runtime.Context.write"><tt class="xref py py-meth docutils literal"><span class="pre">Context.write()</span></tt></a> within its body.</p>
+<p>If your def is to be called in an “embedded content” context,
+that is as described in <a class="reference internal" href="defs.html#defs-with-content"><em>Calling a Def with Embedded Content and/or Other Defs</em></a>, you should use
+the <a class="reference internal" href="#mako.runtime.supports_caller" title="mako.runtime.supports_caller"><tt class="xref py py-func docutils literal"><span class="pre">supports_caller()</span></tt></a> decorator, which will ensure that Mako
+will ensure the correct “caller” variable is available when your
+def is called, supporting embedded content:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.runtime</span> <span class="kn">import</span> <span class="n">supports_caller</span>
+
+<span class="nd">@supports_caller</span>
+<span class="k">def</span> <span class="nf">my_tag</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
+    <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"<div>"</span><span class="p">)</span>
+    <span class="n">context</span><span class="p">[</span><span class="s">'caller'</span><span class="p">]</span><span class="o">.</span><span class="n">body</span><span class="p">()</span>
+    <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"</div>"</span><span class="p">)</span>
+    <span class="k">return</span> <span class="s">''</span>
+</pre></div>
+</div>
+<p>Capturing of output is available as well, using the
+outside-of-templates version of the <a class="reference internal" href="#mako.runtime.capture" title="mako.runtime.capture"><tt class="xref py py-func docutils literal"><span class="pre">capture()</span></tt></a> function,
+which accepts the “context” as its first argument:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.runtime</span> <span class="kn">import</span> <span class="n">supports_caller</span><span class="p">,</span> <span class="n">capture</span>
+
+<span class="nd">@supports_caller</span>
+<span class="k">def</span> <span class="nf">my_tag</span><span class="p">(</span><span class="n">context</span><span class="p">):</span>
+    <span class="k">return</span> <span class="s">"<div></span><span class="si">%s</span><span class="s"></div>"</span> <span class="o">%</span> \
+            <span class="n">capture</span><span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">context</span><span class="p">[</span><span class="s">'caller'</span><span class="p">]</span><span class="o">.</span><span class="n">body</span><span class="p">,</span> <span class="n">x</span><span class="o">=</span><span class="s">"foo"</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="s">"bar"</span><span class="p">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="declaring-defs-in-namespaces">
+<h2>Declaring Defs in Namespaces<a class="headerlink" href="#declaring-defs-in-namespaces" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre"><%namespace></span></tt> tag supports the definition of <tt class="docutils literal"><span class="pre"><%def></span></tt>s
+directly inside the tag. These defs become part of the namespace
+like any other function, and will override the definitions
+pulled in from a remote template or module:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## define a namespace</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">namespace</span> <span class="na">name=</span><span class="s">"stuff"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"comp1()"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        comp1</span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">namespace</span><span class="cp">></span>
+
+<span class="cp">## then call it</span><span class="x"></span>
+<span class="cp">${</span><span class="n">stuff</span><span class="o">.</span><span class="n">comp1</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="the-body-method">
+<span id="namespaces-body"></span><h2>The <tt class="docutils literal"><span class="pre">body()</span></tt> Method<a class="headerlink" href="#the-body-method" title="Permalink to this headline">¶</a></h2>
+<p>Every namespace that is generated from a template contains a
+method called <tt class="docutils literal"><span class="pre">body()</span></tt>. This method corresponds to the main
+body of the template, and plays its most important roles when
+using inheritance relationships as well as
+def-calls-with-content.</p>
+<p>Since the <tt class="docutils literal"><span class="pre">body()</span></tt> method is available from a namespace just
+like all the other defs defined in a template, what happens if
+you send arguments to it? By default, the <tt class="docutils literal"><span class="pre">body()</span></tt> method
+accepts no positional arguments, and for usefulness in
+inheritance scenarios will by default dump all keyword arguments
+into a dictionary called <tt class="docutils literal"><span class="pre">pageargs</span></tt>. But if you actually want
+to get at the keyword arguments, Mako recommends you define your
+own argument signature explicitly. You do this via using the
+<tt class="docutils literal"><span class="pre"><%page></span></tt> tag:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">page</span> <span class="na">args=</span><span class="s">"x, y, someval=8, scope='foo', **kwargs"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>A template which defines the above signature requires that the
+variables <tt class="docutils literal"><span class="pre">x</span></tt> and <tt class="docutils literal"><span class="pre">y</span></tt> are defined, defines default values
+for <tt class="docutils literal"><span class="pre">someval</span></tt> and <tt class="docutils literal"><span class="pre">scope</span></tt>, and sets up <tt class="docutils literal"><span class="pre">**kwargs</span></tt> to
+receive all other keyword arguments. If <tt class="docutils literal"><span class="pre">**kwargs</span></tt> or similar
+is not present, the argument <tt class="docutils literal"><span class="pre">**pageargs</span></tt> gets tacked on by
+Mako. When the template is called as a top-level template (i.e.
+via <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a>) or via the <tt class="docutils literal"><span class="pre"><%include></span></tt> tag, the
+values for these arguments will be pulled from the <tt class="docutils literal"><span class="pre">Context</span></tt>.
+In all other cases, i.e. via calling the <tt class="docutils literal"><span class="pre">body()</span></tt> method, the
+arguments are taken as ordinary arguments from the method call.
+So above, the body might be called as:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">someval</span><span class="o">=</span><span class="mi">15</span><span class="p">,</span> <span class="n">delta</span><span class="o">=</span><span class="mi">7</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object also supplies a <a class="reference internal" href="runtime.html#mako.runtime.Context.kwargs" title="mako.runtime.Context.kwargs"><tt class="xref py py-attr docutils literal"><span class="pre">kwargs</span></tt></a> accessor, for
+cases when you’d like to pass along whatever is in the context to
+a <tt class="docutils literal"><span class="pre">body()</span></tt> callable:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="nb">next</span><span class="o">.</span><span class="n">body</span><span class="p">(</span><span class="o">**</span><span class="n">context</span><span class="o">.</span><span class="n">kwargs</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The usefulness of calls like the above become more apparent when
+one works with inheriting templates. For more information on
+this, as well as the meanings of the names <tt class="docutils literal"><span class="pre">self</span></tt> and
+<tt class="docutils literal"><span class="pre">next</span></tt>, see <a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</p>
+</div>
+<div class="section" id="built-in-namespaces">
+<span id="namespaces-builtin"></span><h2>Built-in Namespaces<a class="headerlink" href="#built-in-namespaces" title="Permalink to this headline">¶</a></h2>
+<p>The namespace is so great that Mako gives your template one (or
+two) for free. The names of these namespaces are <tt class="docutils literal"><span class="pre">local</span></tt> and
+<tt class="docutils literal"><span class="pre">self</span></tt>. Other built-in namespaces include <tt class="docutils literal"><span class="pre">parent</span></tt> and
+<tt class="docutils literal"><span class="pre">next</span></tt>, which are optional and are described in
+<a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</p>
+<div class="section" id="local">
+<span id="namespace-local"></span><h3><tt class="docutils literal"><span class="pre">local</span></tt><a class="headerlink" href="#local" title="Permalink to this headline">¶</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">local</span></tt> namespace is basically the namespace for the
+currently executing template. This means that all of the top
+level defs defined in your template, as well as your template’s
+<tt class="docutils literal"><span class="pre">body()</span></tt> function, are also available off of the <tt class="docutils literal"><span class="pre">local</span></tt>
+namespace.</p>
+<p>The <tt class="docutils literal"><span class="pre">local</span></tt> namespace is also where properties like <tt class="docutils literal"><span class="pre">uri</span></tt>,
+<tt class="docutils literal"><span class="pre">filename</span></tt>, and <tt class="docutils literal"><span class="pre">module</span></tt> and the <tt class="docutils literal"><span class="pre">get_namespace</span></tt> method
+can be particularly useful.</p>
+</div>
+<div class="section" id="self">
+<span id="namespace-self"></span><h3><tt class="docutils literal"><span class="pre">self</span></tt><a class="headerlink" href="#self" title="Permalink to this headline">¶</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">self</span></tt> namespace, in the case of a template that does not
+use inheritance, is synonymous with <tt class="docutils literal"><span class="pre">local</span></tt>. If inheritance is
+used, then <tt class="docutils literal"><span class="pre">self</span></tt> references the topmost template in the
+inheritance chain, where it is most useful for providing the
+ultimate form of various “method” calls which may have been
+overridden at various points in an inheritance chain. See
+<a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</p>
+</div>
+</div>
+<div class="section" id="inheritable-namespaces">
+<h2>Inheritable Namespaces<a class="headerlink" href="#inheritable-namespaces" title="Permalink to this headline">¶</a></h2>
+<p>The <tt class="docutils literal"><span class="pre"><%namespace></span></tt> tag includes an optional attribute
+<tt class="docutils literal"><span class="pre">inheritable="True"</span></tt>, which will cause the namespace to be
+attached to the <tt class="docutils literal"><span class="pre">self</span></tt> namespace. Since <tt class="docutils literal"><span class="pre">self</span></tt> is globally
+available throughout an inheritance chain (described in the next
+section), all the templates in an inheritance chain can get at
+the namespace imported in a super-template via <tt class="docutils literal"><span class="pre">self</span></tt>.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## base.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">namespace</span> <span class="na">name=</span><span class="s">"foo"</span> <span class="na">file=</span><span class="s">"foo.html"</span> <span class="na">inheritable=</span><span class="s">"True"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="cp">${</span><span class="nb">next</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span>
+
+<span class="cp">## somefile.html</span><span class="x"></span>
+<span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"base.html"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">foo</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>This allows a super-template to load a whole bunch of namespaces
+that its inheriting templates can get to, without them having to
+explicitly load those namespaces themselves.</p>
+<p>The <tt class="docutils literal"><span class="pre">import="*"</span></tt> part of the <tt class="docutils literal"><span class="pre"><%namespace></span></tt> tag doesn’t yet
+interact with the <tt class="docutils literal"><span class="pre">inheritable</span></tt> flag, so currently you have to
+use the explicit namespace name off of <tt class="docutils literal"><span class="pre">self</span></tt>, followed by the
+desired function name. But more on this in a future release.</p>
+</div>
+<div class="section" id="api-reference">
+<h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="mako.runtime.Namespace">
+<em class="property">class </em><tt class="descclassname">mako.runtime.</tt><tt class="descname">Namespace</tt><big>(</big><em>name</em>, <em>context</em>, <em>callables=None</em>, <em>inherits=None</em>, <em>populate_self=True</em>, <em>calling_uri=None</em><big>)</big><a class="headerlink" href="#mako.runtime.Namespace" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
+<p>Provides access to collections of rendering methods, which
+can be local, from other templates, or from imported modules.</p>
+<p>To access a particular rendering method referenced by a
+<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>, use plain attribute access:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="n">some_namespace</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p><a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a> also contains several built-in attributes
+described here.</p>
+<dl class="attribute">
+<dt id="mako.runtime.Namespace.attr">
+<tt class="descname">attr</tt><a class="headerlink" href="#mako.runtime.Namespace.attr" title="Permalink to this definition">¶</a></dt>
+<dd><p>Access module level attributes by name.</p>
+<p>This accessor allows templates to supply “scalar”
+attributes which are particularly handy in inheritance
+relationships. See the example in
+<a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.Namespace.cache">
+<tt class="descname">cache</tt><a class="headerlink" href="#mako.runtime.Namespace.cache" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the <a class="reference internal" href="caching.html#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a> object referenced
+by this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a> object’s
+<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.Namespace.context">
+<tt class="descname">context</tt><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.context" title="Permalink to this definition">¶</a></dt>
+<dd><p>The <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object for this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>.</p>
+<p>Namespaces are often created with copies of contexts that
+contain slightly different data, particularly in inheritance
+scenarios. Using the <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> off of a <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a> one
+can traverse an entire chain of templates that inherit from
+one-another.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.Namespace.filename">
+<tt class="descname">filename</tt><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.filename" title="Permalink to this definition">¶</a></dt>
+<dd><p>The path of the filesystem file used for this
+<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>‘s module or template.</p>
+<p>If this is a pure module-based
+<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>, this evaluates to <tt class="docutils literal"><span class="pre">module.__file__</span></tt>. If a
+template-based namespace, it evaluates to the original
+template file location.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Namespace.get_cached">
+<tt class="descname">get_cached</tt><big>(</big><em>key</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#mako.runtime.Namespace.get_cached" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return a value from the <a class="reference internal" href="caching.html#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a> referenced by this
+<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a> object’s <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>.</p>
+<p>The advantage to this method versus direct access to the
+<a class="reference internal" href="caching.html#mako.cache.Cache" title="mako.cache.Cache"><tt class="xref py py-class docutils literal"><span class="pre">Cache</span></tt></a> is that the configuration parameters
+declared in <tt class="docutils literal"><span class="pre"><%page></span></tt> take effect here, thereby calling
+up the same configured backend as that configured
+by <tt class="docutils literal"><span class="pre"><%page></span></tt>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Namespace.get_namespace">
+<tt class="descname">get_namespace</tt><big>(</big><em>uri</em><big>)</big><a class="headerlink" href="#mako.runtime.Namespace.get_namespace" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return a <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a> corresponding to the given <tt class="docutils literal"><span class="pre">uri</span></tt>.</p>
+<p>If the given <tt class="docutils literal"><span class="pre">uri</span></tt> is a relative URI (i.e. it does not
+contain a leading slash <tt class="docutils literal"><span class="pre">/</span></tt>), the <tt class="docutils literal"><span class="pre">uri</span></tt> is adjusted to
+be relative to the <tt class="docutils literal"><span class="pre">uri</span></tt> of the namespace itself. This
+method is therefore mostly useful off of the built-in
+<tt class="docutils literal"><span class="pre">local</span></tt> namespace, described in <a class="reference internal" href="#namespace-local"><em>local</em></a>.</p>
+<p>In
+most cases, a template wouldn’t need this function, and
+should instead use the <tt class="docutils literal"><span class="pre"><%namespace></span></tt> tag to load
+namespaces. However, since all <tt class="docutils literal"><span class="pre"><%namespace></span></tt> tags are
+evaluated before the body of a template ever runs,
+this method can be used to locate namespaces using
+expressions that were generated within the body code of
+the template, or to conditionally use a particular
+namespace.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Namespace.get_template">
+<tt class="descname">get_template</tt><big>(</big><em>uri</em><big>)</big><a class="headerlink" href="#mako.runtime.Namespace.get_template" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> from the given <tt class="docutils literal"><span class="pre">uri</span></tt>.</p>
+<p>The <tt class="docutils literal"><span class="pre">uri</span></tt> resolution is relative to the <tt class="docutils literal"><span class="pre">uri</span></tt> of this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>
+object’s <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Namespace.include_file">
+<tt class="descname">include_file</tt><big>(</big><em>uri</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#mako.runtime.Namespace.include_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>Include a file at the given <tt class="docutils literal"><span class="pre">uri</span></tt>.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.Namespace.module">
+<tt class="descname">module</tt><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.module" title="Permalink to this definition">¶</a></dt>
+<dd><p>The Python module referenced by this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>.</p>
+<p>If the namespace references a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>, then
+this module is the equivalent of <tt class="docutils literal"><span class="pre">template.module</span></tt>,
+i.e. the generated module for the template.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.Namespace.template">
+<tt class="descname">template</tt><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.template" title="Permalink to this definition">¶</a></dt>
+<dd><p>The <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object referenced by this
+<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>, if any.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.Namespace.uri">
+<tt class="descname">uri</tt><em class="property"> = None</em><a class="headerlink" href="#mako.runtime.Namespace.uri" title="Permalink to this definition">¶</a></dt>
+<dd><p>The URI for this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>‘s template.</p>
+<p>I.e. whatever was sent to <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><tt class="xref py py-meth docutils literal"><span class="pre">TemplateLookup.get_template()</span></tt></a>.</p>
+<p>This is the equivalent of <tt class="xref py py-attr docutils literal"><span class="pre">Template.uri</span></tt>.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="mako.runtime.TemplateNamespace">
+<em class="property">class </em><tt class="descclassname">mako.runtime.</tt><tt class="descname">TemplateNamespace</tt><big>(</big><em>name</em>, <em>context</em>, <em>template=None</em>, <em>templateuri=None</em>, <em>callables=None</em>, <em>inherits=None</em>, <em>populate_self=True</em>, <em>calling_uri=None</em><big>)</big><a class="headerlink" href="#mako.runtime.TemplateNamespace" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">mako.runtime.Namespace</span></tt></a></p>
+<p>A <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a> specific to a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> instance.</p>
+<dl class="attribute">
+<dt id="mako.runtime.TemplateNamespace.filename">
+<tt class="descname">filename</tt><a class="headerlink" href="#mako.runtime.TemplateNamespace.filename" title="Permalink to this definition">¶</a></dt>
+<dd><p>The path of the filesystem file used for this
+<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>‘s module or template.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.TemplateNamespace.module">
+<tt class="descname">module</tt><a class="headerlink" href="#mako.runtime.TemplateNamespace.module" title="Permalink to this definition">¶</a></dt>
+<dd><p>The Python module referenced by this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>.</p>
+<p>If the namespace references a <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>, then
+this module is the equivalent of <tt class="docutils literal"><span class="pre">template.module</span></tt>,
+i.e. the generated module for the template.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.TemplateNamespace.uri">
+<tt class="descname">uri</tt><a class="headerlink" href="#mako.runtime.TemplateNamespace.uri" title="Permalink to this definition">¶</a></dt>
+<dd><p>The URI for this <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>‘s template.</p>
+<p>I.e. whatever was sent to <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><tt class="xref py py-meth docutils literal"><span class="pre">TemplateLookup.get_template()</span></tt></a>.</p>
+<p>This is the equivalent of <tt class="xref py py-attr docutils literal"><span class="pre">Template.uri</span></tt>.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="mako.runtime.ModuleNamespace">
+<em class="property">class </em><tt class="descclassname">mako.runtime.</tt><tt class="descname">ModuleNamespace</tt><big>(</big><em>name</em>, <em>context</em>, <em>module</em>, <em>callables=None</em>, <em>inherits=None</em>, <em>populate_self=True</em>, <em>calling_uri=None</em><big>)</big><a class="headerlink" href="#mako.runtime.ModuleNamespace" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">mako.runtime.Namespace</span></tt></a></p>
+<p>A <a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a> specific to a Python module instance.</p>
+<dl class="attribute">
+<dt id="mako.runtime.ModuleNamespace.filename">
+<tt class="descname">filename</tt><a class="headerlink" href="#mako.runtime.ModuleNamespace.filename" title="Permalink to this definition">¶</a></dt>
+<dd><p>The path of the filesystem file used for this
+<a class="reference internal" href="#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>‘s module or template.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="mako.runtime.supports_caller">
+<tt class="descclassname">mako.runtime.</tt><tt class="descname">supports_caller</tt><big>(</big><em>func</em><big>)</big><a class="headerlink" href="#mako.runtime.supports_caller" title="Permalink to this definition">¶</a></dt>
+<dd><p>Apply a caller_stack compatibility decorator to a plain
+Python function.</p>
+<p>See the example in <a class="reference internal" href="#namespaces-python-modules"><em>Namespaces from Regular Python Modules</em></a>.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="mako.runtime.capture">
+<tt class="descclassname">mako.runtime.</tt><tt class="descname">capture</tt><big>(</big><em>context</em>, <em>callable_</em>, <em>*args</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#mako.runtime.capture" title="Permalink to this definition">¶</a></dt>
+<dd><p>Execute the given template def, capturing the output into
+a buffer.</p>
+<p>See the example in <a class="reference internal" href="#namespaces-python-modules"><em>Namespaces from Regular Python Modules</em></a>.</p>
+</dd></dl>
+
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Previous:
+        <a href="runtime.html" title="previous chapter">The Mako Runtime Environment</a>
+        Next:
+        <a href="inheritance.html" title="next chapter">Inheritance</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/runtime.html b/lib3/Mako-0.7.3/doc/runtime.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/runtime.html
@@ -0,0 +1,710 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+                The Mako Runtime Environment
+             — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+        <link rel="next" title="Namespaces" href="namespaces.html" />
+        <link rel="prev" title="Defs and Blocks" href="defs.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Prev:
+            <a href="defs.html" title="previous chapter">Defs and Blocks</a>
+            </li>
+            <li>Next:
+            <a href="namespaces.html" title="next chapter">Namespaces</a>
+            </li>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/runtime.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+                The Mako Runtime Environment
+             
+
+        <h2>
+            
+                The Mako Runtime Environment
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+    <div id="docs-sidebar">
+    <h3><a href="index.html">Table of Contents</a></h3>
+    <ul>
+<li><a class="reference internal" href="#">The Mako Runtime Environment</a><ul>
+<li><a class="reference internal" href="#context">Context</a><ul>
+<li><a class="reference internal" href="#the-buffer">The Buffer</a></li>
+<li><a class="reference internal" href="#context-variables">Context Variables</a></li>
+<li><a class="reference internal" href="#context-methods-and-accessors">Context Methods and Accessors</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#the-loop-context">The Loop Context</a><ul>
+<li><a class="reference internal" href="#iterations">Iterations</a></li>
+<li><a class="reference internal" href="#cycling">Cycling</a></li>
+<li><a class="reference internal" href="#parent-loops">Parent Loops</a></li>
+<li><a class="reference internal" href="#migrating-legacy-templates-that-use-the-word-loop">Migrating Legacy Templates that Use the Word “loop”</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#all-the-built-in-names">All the Built-in Names</a><ul>
+<li><a class="reference internal" href="#reserved-names">Reserved Names</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#api-reference">API Reference</a></li>
+</ul>
+</li>
+</ul>
+
+
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="defs.html" title="previous chapter">Defs and Blocks</a>
+    </p>
+    <h4>Next Topic</h4>
+    <p>
+    <a href="namespaces.html" title="next chapter">Namespaces</a>
+    </p>
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+
+    <div id="docs-body" class="withsidebar" >
+        
+<div class="section" id="the-mako-runtime-environment">
+<span id="runtime-toplevel"></span><h1>The Mako Runtime Environment<a class="headerlink" href="#the-mako-runtime-environment" title="Permalink to this headline">¶</a></h1>
+<p>This section describes a little bit about the objects and
+built-in functions that are available in templates.</p>
+<div class="section" id="context">
+<span id="id1"></span><h2>Context<a class="headerlink" href="#context" title="Permalink to this headline">¶</a></h2>
+<p>The <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> is the central object that is created when
+a template is first executed, and is responsible for handling
+all communication with the outside world.  Within the template
+environment, it is available via the <a class="reference internal" href="#reserved-names"><em>reserved name</em></a>
+<tt class="docutils literal"><span class="pre">context</span></tt>.  The <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> includes two
+major components, one of which is the output buffer, which is a
+file-like object such as Python’s <tt class="docutils literal"><span class="pre">StringIO</span></tt> or similar, and
+the other a dictionary of variables that can be freely
+referenced within a template; this dictionary is a combination
+of the arguments sent to the <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a> function and
+some built-in variables provided by Mako’s runtime environment.</p>
+<div class="section" id="the-buffer">
+<h3>The Buffer<a class="headerlink" href="#the-buffer" title="Permalink to this headline">¶</a></h3>
+<p>The buffer is stored within the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>, and writing
+to it is achieved by calling the <a class="reference internal" href="#mako.runtime.Context.write" title="mako.runtime.Context.write"><tt class="xref py py-meth docutils literal"><span class="pre">write()</span></tt></a> method
+– in a template this looks like <tt class="docutils literal"><span class="pre">context.write('some</span> <span class="pre">string')</span></tt>.
+You usually don’t need to care about this, as all text within a template, as
+well as all expressions provided by <tt class="docutils literal"><span class="pre">${}</span></tt>, automatically send
+everything to this method. The cases you might want to be aware
+of its existence are if you are dealing with various
+filtering/buffering scenarios, which are described in
+<a class="reference internal" href="filtering.html"><em>Filtering and Buffering</em></a>, or if you want to programmatically
+send content to the output stream, such as within a <tt class="docutils literal"><span class="pre"><%</span> <span class="pre">%></span></tt>
+block.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span>
+    <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"some programmatic text"</span><span class="p">)</span>
+<span class="cp">%></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The actual buffer may or may not be the original buffer sent to
+the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object, as various filtering/caching
+scenarios may “push” a new buffer onto the context’s underlying
+buffer stack. For this reason, just stick with
+<tt class="docutils literal"><span class="pre">context.write()</span></tt> and content will always go to the topmost
+buffer.</p>
+</div>
+<div class="section" id="context-variables">
+<span id="context-vars"></span><h3>Context Variables<a class="headerlink" href="#context-variables" title="Permalink to this headline">¶</a></h3>
+<p>When your template is compiled into a Python module, the body
+content is enclosed within a Python function called
+<tt class="docutils literal"><span class="pre">render_body</span></tt>. Other top-level defs defined in the template are
+defined within their own function bodies which are named after
+the def’s name with the prefix <tt class="docutils literal"><span class="pre">render_</span></tt> (i.e. <tt class="docutils literal"><span class="pre">render_mydef</span></tt>).
+One of the first things that happens within these functions is
+that all variable names that are referenced within the function
+which are not defined in some other way (i.e. such as via
+assignment, module level imports, etc.) are pulled from the
+<a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object’s dictionary of variables. This is how you’re
+able to freely reference variable names in a template which
+automatically correspond to what was passed into the current
+<a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>.</p>
+<ul>
+<li><p class="first"><strong>What happens if I reference a variable name that is not in
+the current context?</strong> - The value you get back is a special
+value called <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt>, or if the <tt class="docutils literal"><span class="pre">strict_undefined=True</span></tt> flag
+is used a <tt class="docutils literal"><span class="pre">NameError</span></tt> is raised. <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> is just a simple global
+variable with the class <a class="reference internal" href="#mako.runtime.Undefined" title="mako.runtime.Undefined"><tt class="xref py py-class docutils literal"><span class="pre">mako.runtime.Undefined</span></tt></a>. The
+<tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> object throws an error when you call <tt class="docutils literal"><span class="pre">str()</span></tt> on
+it, which is what happens if you try to use it in an
+expression.</p>
+</li>
+<li><p class="first"><strong>UNDEFINED makes it hard for me to find what name is missing</strong> - An alternative
+is to specify the option <tt class="docutils literal"><span class="pre">strict_undefined=True</span></tt>
+to the <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> or <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>.  This will cause
+any non-present variables to raise an immediate <tt class="docutils literal"><span class="pre">NameError</span></tt>
+which includes the name of the variable in its message
+when <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a> is called – <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> is not used.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.3.6.</span></p>
+</li>
+<li><p class="first"><strong>Why not just return None?</strong> Using <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt>, or
+raising a <tt class="docutils literal"><span class="pre">NameError</span></tt> is more
+explicit and allows differentiation between a value of <tt class="docutils literal"><span class="pre">None</span></tt>
+that was explicitly passed to the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> and a value that
+wasn’t present at all.</p>
+</li>
+<li><p class="first"><strong>Why raise an exception when you call str() on it ? Why not
+just return a blank string?</strong> - Mako tries to stick to the
+Python philosophy of “explicit is better than implicit”. In
+this case, it’s decided that the template author should be made
+to specifically handle a missing value rather than
+experiencing what may be a silent failure. Since <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt>
+is a singleton object just like Python’s <tt class="docutils literal"><span class="pre">True</span></tt> or <tt class="docutils literal"><span class="pre">False</span></tt>,
+you can use the <tt class="docutils literal"><span class="pre">is</span></tt> operator to check for it:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">%</span> <span class="k">if</span> <span class="n">someval</span> <span class="ow">is</span> <span class="n">UNDEFINED</span><span class="p">:</span><span class="x"></span>
+<span class="x">    someval is: no value</span>
+<span class="cp">%</span> <span class="k">else</span><span class="p">:</span><span class="x"></span>
+<span class="x">    someval is: </span><span class="cp">${</span><span class="n">someval</span><span class="cp">}</span>
+<span class="cp">%</span><span class="k"> endif</span><span class="x"></span>
+</pre></div>
+</div>
+</li>
+</ul>
+<p>Another facet of the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> is that its dictionary of
+variables is <strong>immutable</strong>. Whatever is set when
+<a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a> is called is what stays. Of course, since
+its Python, you can hack around this and change values in the
+context’s internal dictionary, but this will probably will not
+work as well as you’d think. The reason for this is that Mako in
+many cases creates copies of the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object, which
+get sent to various elements of the template and inheriting
+templates used in an execution. So changing the value in your
+local <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> will not necessarily make that value
+available in other parts of the template’s execution. Examples
+of where Mako creates copies of the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> include
+within top-level def calls from the main body of the template
+(the context is used to propagate locally assigned variables
+into the scope of defs; since in the template’s body they appear
+as inlined functions, Mako tries to make them act that way), and
+within an inheritance chain (each template in an inheritance
+chain has a different notion of <tt class="docutils literal"><span class="pre">parent</span></tt> and <tt class="docutils literal"><span class="pre">next</span></tt>, which
+are all stored in unique <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> instances).</p>
+<ul>
+<li><p class="first"><strong>So what if I want to set values that are global to everyone
+within a template request?</strong> - All you have to do is provide a
+dictionary to your <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> when the template first
+runs, and everyone can just get/set variables from that. Lets
+say its called <tt class="docutils literal"><span class="pre">attributes</span></tt>.</p>
+<p>Running the template looks like:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">output</span> <span class="o">=</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">attributes</span><span class="o">=</span><span class="p">{})</span>
+</pre></div>
+</div>
+<p>Within a template, just reference the dictionary:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span>
+    <span class="n">attributes</span><span class="p">[</span><span class="s">'foo'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'bar'</span>
+<span class="cp">%></span><span class="x"></span>
+<span class="x">'foo' attribute is: </span><span class="cp">${</span><span class="n">attributes</span><span class="p">[</span><span class="s">'foo'</span><span class="p">]</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+</li>
+<li><p class="first"><strong>Why can’t “attributes” be a built-in feature of the
+Context?</strong> - This is an area where Mako is trying to make as
+few decisions about your application as it possibly can.
+Perhaps you don’t want your templates to use this technique of
+assigning and sharing data, or perhaps you have a different
+notion of the names and kinds of data structures that should
+be passed around. Once again Mako would rather ask the user to
+be explicit.</p>
+</li>
+</ul>
+</div>
+<div class="section" id="context-methods-and-accessors">
+<h3>Context Methods and Accessors<a class="headerlink" href="#context-methods-and-accessors" title="Permalink to this headline">¶</a></h3>
+<p>Significant members of <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> include:</p>
+<ul>
+<li><p class="first"><tt class="docutils literal"><span class="pre">context[key]</span></tt> / <tt class="docutils literal"><span class="pre">context.get(key,</span> <span class="pre">default=None)</span></tt> -
+dictionary-like accessors for the context. Normally, any
+variable you use in your template is automatically pulled from
+the context if it isn’t defined somewhere already. Use the
+dictionary accessor and/or <tt class="docutils literal"><span class="pre">get</span></tt> method when you want a
+variable that <em>is</em> already defined somewhere else, such as in
+the local arguments sent to a <tt class="docutils literal"><span class="pre">%def</span></tt> call. If a key is not
+present, like a dictionary it raises <tt class="docutils literal"><span class="pre">KeyError</span></tt>.</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">keys()</span></tt> - all the names defined within this context.</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">kwargs</span></tt> - this returns a <strong>copy</strong> of the context’s
+dictionary of variables. This is useful when you want to
+propagate the variables in the current context to a function
+as keyword arguments, i.e.:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="nb">next</span><span class="o">.</span><span class="n">body</span><span class="p">(</span><span class="o">**</span><span class="n">context</span><span class="o">.</span><span class="n">kwargs</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">write(text)</span></tt> - write some text to the current output
+stream.</p>
+</li>
+<li><p class="first"><tt class="docutils literal"><span class="pre">lookup</span></tt> - returns the <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> instance that is
+used for all file-lookups within the current execution (even
+though individual <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> instances can conceivably have
+different instances of a <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>, only the
+<a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> of the originally-called <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> gets
+used in a particular execution).</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="section" id="the-loop-context">
+<span id="loop-context"></span><h2>The Loop Context<a class="headerlink" href="#the-loop-context" title="Permalink to this headline">¶</a></h2>
+<p>Within <tt class="docutils literal"><span class="pre">%</span> <span class="pre">for</span></tt> blocks, the <a class="reference internal" href="#reserved-names"><em>reserved name</em></a> <tt class="docutils literal"><span class="pre">loop</span></tt>
+is available.  <tt class="docutils literal"><span class="pre">loop</span></tt> tracks the progress of
+the <tt class="docutils literal"><span class="pre">for</span></tt> loop and makes it easy to use the iteration state to control
+template behavior:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><ul></span>
+<span class="cp">%</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="p">(</span><span class="s">"one"</span><span class="p">,</span> <span class="s">"two"</span><span class="p">,</span> <span class="s">"three"</span><span class="p">):</span><span class="x"></span>
+<span class="x">    <li>Item </span><span class="cp">${</span><span class="n">loop</span><span class="o">.</span><span class="n">index</span><span class="cp">}</span><span class="x">: </span><span class="cp">${</span><span class="n">a</span><span class="cp">}</span><span class="x"></li></span>
+<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="x"></ul></span>
+</pre></div>
+</div>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.7.</span></p>
+<div class="section" id="iterations">
+<h3>Iterations<a class="headerlink" href="#iterations" title="Permalink to this headline">¶</a></h3>
+<p>Regardless of the type of iterable you’re looping over, <tt class="docutils literal"><span class="pre">loop</span></tt> always tracks
+the 0-indexed iteration count (available at <tt class="docutils literal"><span class="pre">loop.index</span></tt>), its parity
+(through the <tt class="docutils literal"><span class="pre">loop.even</span></tt> and <tt class="docutils literal"><span class="pre">loop.odd</span></tt> bools), and <tt class="docutils literal"><span class="pre">loop.first</span></tt>, a bool
+indicating whether the loop is on its first iteration.  If your iterable
+provides a <tt class="docutils literal"><span class="pre">__len__</span></tt> method, <tt class="docutils literal"><span class="pre">loop</span></tt> also provides access to
+a count of iterations remaining at <tt class="docutils literal"><span class="pre">loop.reverse_index</span></tt> and <tt class="docutils literal"><span class="pre">loop.last</span></tt>,
+a bool indicating whether the loop is on its last iteration; accessing these
+without <tt class="docutils literal"><span class="pre">__len__</span></tt> will raise a <tt class="docutils literal"><span class="pre">TypeError</span></tt>.</p>
+</div>
+<div class="section" id="cycling">
+<h3>Cycling<a class="headerlink" href="#cycling" title="Permalink to this headline">¶</a></h3>
+<p>Cycling is available regardless of whether the iterable you’re using provides
+a <tt class="docutils literal"><span class="pre">__len__</span></tt> method.  Prior to Mako 0.7, you might have generated a simple
+zebra striped list using <tt class="docutils literal"><span class="pre">enumerate</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><ul></span>
+<span class="cp">%</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">((</span><span class="s">'spam'</span><span class="p">,</span> <span class="s">'ham'</span><span class="p">,</span> <span class="s">'eggs'</span><span class="p">)):</span><span class="x"></span>
+<span class="x">  <li class="</span><span class="cp">${</span><span class="s">'odd'</span> <span class="k">if</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="k">else</span> <span class="s">'even'</span><span class="cp">}</span><span class="x">"></span><span class="cp">${</span><span class="n">item</span><span class="cp">}</span><span class="x"></li></span>
+<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="x"></ul></span>
+</pre></div>
+</div>
+<p>With <tt class="docutils literal"><span class="pre">loop.cycle</span></tt>, you get the same results with cleaner code and less prep work:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><ul></span>
+<span class="cp">%</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'spam'</span><span class="p">,</span> <span class="s">'ham'</span><span class="p">,</span> <span class="s">'eggs'</span><span class="p">):</span><span class="x"></span>
+<span class="x">  <li class="</span><span class="cp">${</span><span class="n">loop</span><span class="o">.</span><span class="n">cycle</span><span class="p">(</span><span class="s">'even'</span><span class="p">,</span> <span class="s">'odd'</span><span class="p">)</span><span class="cp">}</span><span class="x">"></span><span class="cp">${</span><span class="n">item</span><span class="cp">}</span><span class="x"></li></span>
+<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="x"></ul></span>
+</pre></div>
+</div>
+<p>Both approaches produce output like the following:</p>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><ul></span>
+  <span class="nt"><li</span> <span class="na">class=</span><span class="s">"even"</span><span class="nt">></span>spam<span class="nt"></li></span>
+  <span class="nt"><li</span> <span class="na">class=</span><span class="s">"odd"</span><span class="nt">></span>ham<span class="nt"></li></span>
+  <span class="nt"><li</span> <span class="na">class=</span><span class="s">"even"</span><span class="nt">></span>eggs<span class="nt"></li></span>
+<span class="nt"></ul></span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="parent-loops">
+<h3>Parent Loops<a class="headerlink" href="#parent-loops" title="Permalink to this headline">¶</a></h3>
+<p>Loop contexts can also be transparently nested, and the Mako runtime will do
+the right thing and manage the scope for you.  You can access the parent loop
+context through <tt class="docutils literal"><span class="pre">loop.parent</span></tt>.</p>
+<p>This allows you to reach all the way back up through the loop stack by
+chaining <tt class="docutils literal"><span class="pre">parent</span></tt> attribute accesses, i.e. <tt class="docutils literal"><span class="pre">loop.parent.parent....</span></tt> as
+long as the stack depth isn’t exceeded.  For example, you can use the parent
+loop to make a checkered table:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><table></span>
+<span class="cp">%</span> <span class="k">for</span> <span class="n">consonant</span> <span class="ow">in</span> <span class="s">'pbj'</span><span class="p">:</span><span class="x"></span>
+<span class="x">  <tr></span>
+  <span class="cp">%</span> <span class="k">for</span> <span class="n">vowel</span> <span class="ow">in</span> <span class="s">'iou'</span><span class="p">:</span><span class="x"></span>
+<span class="x">    <td class="</span><span class="cp">${</span><span class="s">'black'</span> <span class="k">if</span> <span class="p">(</span><span class="n">loop</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">even</span> <span class="o">==</span> <span class="n">loop</span><span class="o">.</span><span class="n">even</span><span class="p">)</span> <span class="k">else</span> <span class="s">'red'</span><span class="cp">}</span><span class="x">"></span>
+<span class="x">      </span><span class="cp">${</span><span class="n">consonant</span> <span class="o">+</span> <span class="n">vowel</span><span class="cp">}</span><span class="x">t</span>
+<span class="x">    </td></span>
+  <span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="x">  </tr></span>
+<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="x"></table></span>
+</pre></div>
+</div>
+<div class="highlight-html"><div class="highlight"><pre><span class="nt"><table></span>
+  <span class="nt"><tr></span>
+    <span class="nt"><td</span> <span class="na">class=</span><span class="s">"black"</span><span class="nt">></span>
+      pit
+    <span class="nt"></td></span>
+    <span class="nt"><td</span> <span class="na">class=</span><span class="s">"red"</span><span class="nt">></span>
+      pot
+    <span class="nt"></td></span>
+    <span class="nt"><td</span> <span class="na">class=</span><span class="s">"black"</span><span class="nt">></span>
+      put
+    <span class="nt"></td></span>
+  <span class="nt"></tr></span>
+  <span class="nt"><tr></span>
+    <span class="nt"><td</span> <span class="na">class=</span><span class="s">"red"</span><span class="nt">></span>
+      bit
+    <span class="nt"></td></span>
+    <span class="nt"><td</span> <span class="na">class=</span><span class="s">"black"</span><span class="nt">></span>
+      bot
+    <span class="nt"></td></span>
+    <span class="nt"><td</span> <span class="na">class=</span><span class="s">"red"</span><span class="nt">></span>
+      but
+    <span class="nt"></td></span>
+  <span class="nt"></tr></span>
+  <span class="nt"><tr></span>
+    <span class="nt"><td</span> <span class="na">class=</span><span class="s">"black"</span><span class="nt">></span>
+      jit
+    <span class="nt"></td></span>
+    <span class="nt"><td</span> <span class="na">class=</span><span class="s">"red"</span><span class="nt">></span>
+      jot
+    <span class="nt"></td></span>
+    <span class="nt"><td</span> <span class="na">class=</span><span class="s">"black"</span><span class="nt">></span>
+      jut
+    <span class="nt"></td></span>
+  <span class="nt"></tr></span>
+<span class="nt"></table></span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="migrating-legacy-templates-that-use-the-word-loop">
+<span id="migrating-loop"></span><h3>Migrating Legacy Templates that Use the Word “loop”<a class="headerlink" href="#migrating-legacy-templates-that-use-the-word-loop" title="Permalink to this headline">¶</a></h3>
+<p class="versionchanged">
+<span class="versionmodified">Changed in version 0.7: </span>The <tt class="docutils literal"><span class="pre">loop</span></tt> name is now <a class="reference internal" href="#reserved-names"><em>reserved</em></a> in Mako,
+which means a template that refers to a variable named <tt class="docutils literal"><span class="pre">loop</span></tt>
+won’t function correctly when used in Mako 0.7.</p>
+<p>To ease the transition for such systems, the feature can be disabled across the board for
+all templates, then re-enabled on a per-template basis for those templates which wish
+to make use of the new system.</p>
+<p>First, the <tt class="docutils literal"><span class="pre">enable_loop=False</span></tt> flag is passed to either the <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>
+or <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object in use:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/docs'</span><span class="p">],</span> <span class="n">enable_loop</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>or:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s">"some template"</span><span class="p">,</span> <span class="n">enable_loop</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>An individual template can make usage of the feature when <tt class="docutils literal"><span class="pre">enable_loop</span></tt> is set to
+<tt class="docutils literal"><span class="pre">False</span></tt> by switching it back on within the <tt class="docutils literal"><span class="pre"><%page></span></tt> tag:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">page</span> <span class="na">enable_loop=</span><span class="s">"True"</span><span class="cp">/></span>
+
+<span class="cp">%</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">collection</span><span class="p">:</span><span class="x"></span>
+<span class="x">    </span><span class="cp">${</span><span class="n">i</span><span class="cp">}</span><span class="x"> </span><span class="cp">${</span><span class="n">loop</span><span class="o">.</span><span class="n">index</span><span class="cp">}</span>
+<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Using the above scheme, it’s safe to pass the name <tt class="docutils literal"><span class="pre">loop</span></tt> to the <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">Template.render()</span></tt></a>
+method as well as to freely make usage of a variable named <tt class="docutils literal"><span class="pre">loop</span></tt> within a template, provided
+the <tt class="docutils literal"><span class="pre"><%page></span></tt> tag doesn’t override it.  New templates that want to use the <tt class="docutils literal"><span class="pre">loop</span></tt> context
+can then set up <tt class="docutils literal"><span class="pre"><%page</span> <span class="pre">enable_loop="True"/></span></tt> to use the new feature without affecting
+old templates.</p>
+</div>
+</div>
+<div class="section" id="all-the-built-in-names">
+<h2>All the Built-in Names<a class="headerlink" href="#all-the-built-in-names" title="Permalink to this headline">¶</a></h2>
+<p>A one-stop shop for all the names Mako defines. Most of these
+names are instances of <a class="reference internal" href="namespaces.html#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">Namespace</span></tt></a>, which are described
+in the next section, <a class="reference internal" href="namespaces.html"><em>Namespaces</em></a>. Also, most of
+these names other than <tt class="docutils literal"><span class="pre">context</span></tt>, <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt>, and <tt class="docutils literal"><span class="pre">loop</span></tt> are
+also present <em>within</em> the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> itself.   The names
+<tt class="docutils literal"><span class="pre">context</span></tt>, <tt class="docutils literal"><span class="pre">loop</span></tt> and <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> themselves can’t be passed
+to the context and can’t be substituted – see the section <a class="reference internal" href="#reserved-names"><em>Reserved Names</em></a>.</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">context</span></tt> - this is the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object, introduced
+at <a class="reference internal" href="#context"><em>Context</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">local</span></tt> - the namespace of the current template, described
+in <a class="reference internal" href="namespaces.html#namespaces-builtin"><em>Built-in Namespaces</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">self</span></tt> - the namespace of the topmost template in an
+inheritance chain (if any, otherwise the same as <tt class="docutils literal"><span class="pre">local</span></tt>),
+mostly described in <a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">parent</span></tt> - the namespace of the parent template in an
+inheritance chain (otherwise undefined); see
+<a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">next</span></tt> - the namespace of the next template in an
+inheritance chain (otherwise undefined); see
+<a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">caller</span></tt> - a “mini” namespace created when using the
+<tt class="docutils literal"><span class="pre"><%call></span></tt> tag to define a “def call with content”; described
+in <a class="reference internal" href="defs.html#defs-with-content"><em>Calling a Def with Embedded Content and/or Other Defs</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">loop</span></tt> - this provides access to <a class="reference internal" href="#mako.runtime.LoopContext" title="mako.runtime.LoopContext"><tt class="xref py py-class docutils literal"><span class="pre">LoopContext</span></tt></a> objects when
+they are requested within <tt class="docutils literal"><span class="pre">%</span> <span class="pre">for</span></tt> loops, introduced at <a class="reference internal" href="#loop-context"><em>The Loop Context</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">capture</span></tt> - a function that calls a given def and captures
+its resulting content into a string, which is returned. Usage
+is described in <a class="reference internal" href="filtering.html"><em>Filtering and Buffering</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> - a global singleton that is applied to all
+otherwise uninitialized template variables that were not
+located within the <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> when rendering began,
+unless the <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> flag <tt class="docutils literal"><span class="pre">strict_undefined</span></tt>
+is set to <tt class="docutils literal"><span class="pre">True</span></tt>. <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> is
+an instance of <a class="reference internal" href="#mako.runtime.Undefined" title="mako.runtime.Undefined"><tt class="xref py py-class docutils literal"><span class="pre">Undefined</span></tt></a>, and raises an
+exception when its <tt class="docutils literal"><span class="pre">__str__()</span></tt> method is called.</li>
+<li><tt class="docutils literal"><span class="pre">pageargs</span></tt> - this is a dictionary which is present in a
+template which does not define any <tt class="docutils literal"><span class="pre">**kwargs</span></tt> section in its
+<tt class="docutils literal"><span class="pre"><%page></span></tt> tag. All keyword arguments sent to the <tt class="docutils literal"><span class="pre">body()</span></tt>
+function of a template (when used via namespaces) go here by
+default unless otherwise defined as a page argument. If this
+makes no sense, it shouldn’t; read the section
+<a class="reference internal" href="namespaces.html#namespaces-body"><em>The body() Method</em></a>.</li>
+</ul>
+<div class="section" id="reserved-names">
+<span id="id2"></span><h3>Reserved Names<a class="headerlink" href="#reserved-names" title="Permalink to this headline">¶</a></h3>
+<p>Mako has a few names that are considered to be “reserved” and can’t be used
+as variable names.</p>
+<p class="versionchanged">
+<span class="versionmodified">Changed in version 0.7: </span>Mako raises an error if these words are found passed to the template
+as context arguments, whereas in previous versions they’d be silently
+ignored or lead to other error messages.</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">context</span></tt> - see <a class="reference internal" href="#context"><em>Context</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> - see <a class="reference internal" href="#context-vars"><em>Context Variables</em></a>.</li>
+<li><tt class="docutils literal"><span class="pre">loop</span></tt> - see <a class="reference internal" href="#loop-context"><em>The Loop Context</em></a>.  Note this can be disabled for legacy templates
+via the <tt class="docutils literal"><span class="pre">enable_loop=False</span></tt> argument; see <a class="reference internal" href="#migrating-loop"><em>Migrating Legacy Templates that Use the Word “loop”</em></a>.</li>
+</ul>
+</div>
+</div>
+<div class="section" id="api-reference">
+<h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="mako.runtime.Context">
+<em class="property">class </em><tt class="descclassname">mako.runtime.</tt><tt class="descname">Context</tt><big>(</big><em>buffer</em>, <em>**data</em><big>)</big><a class="headerlink" href="#mako.runtime.Context" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
+<p>Provides runtime namespace, output buffer, and various
+callstacks for templates.</p>
+<p>See <a class="reference internal" href="#"><em>The Mako Runtime Environment</em></a> for detail on the usage of
+<a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>.</p>
+<dl class="method">
+<dt id="mako.runtime.Context.get">
+<tt class="descname">get</tt><big>(</big><em>key</em>, <em>default=None</em><big>)</big><a class="headerlink" href="#mako.runtime.Context.get" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return a value from this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Context.keys">
+<tt class="descname">keys</tt><big>(</big><big>)</big><a class="headerlink" href="#mako.runtime.Context.keys" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return a list of all names established in this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.Context.kwargs">
+<tt class="descname">kwargs</tt><a class="headerlink" href="#mako.runtime.Context.kwargs" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the dictionary of keyword arguments associated with this
+<a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Context.locals_">
+<tt class="descname">locals_</tt><big>(</big><em>d</em><big>)</big><a class="headerlink" href="#mako.runtime.Context.locals_" title="Permalink to this definition">¶</a></dt>
+<dd><p>Create a new <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> with a copy of this
+<a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>‘s current state, updated with the given dictionary.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.runtime.Context.lookup">
+<tt class="descname">lookup</tt><a class="headerlink" href="#mako.runtime.Context.lookup" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> associated
+with this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Context.pop_caller">
+<tt class="descname">pop_caller</tt><big>(</big><big>)</big><a class="headerlink" href="#mako.runtime.Context.pop_caller" title="Permalink to this definition">¶</a></dt>
+<dd><p>Pop a <tt class="docutils literal"><span class="pre">caller</span></tt> callable onto the callstack for this
+<a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Context.push_caller">
+<tt class="descname">push_caller</tt><big>(</big><em>caller</em><big>)</big><a class="headerlink" href="#mako.runtime.Context.push_caller" title="Permalink to this definition">¶</a></dt>
+<dd><p>Push a <tt class="docutils literal"><span class="pre">caller</span></tt> callable onto the callstack for
+this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Context.write">
+<tt class="descname">write</tt><big>(</big><em>string</em><big>)</big><a class="headerlink" href="#mako.runtime.Context.write" title="Permalink to this definition">¶</a></dt>
+<dd><p>Write a string to this <a class="reference internal" href="#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object’s
+underlying output buffer.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.runtime.Context.writer">
+<tt class="descname">writer</tt><big>(</big><big>)</big><a class="headerlink" href="#mako.runtime.Context.writer" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the current writer function.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="mako.runtime.LoopContext">
+<em class="property">class </em><tt class="descclassname">mako.runtime.</tt><tt class="descname">LoopContext</tt><big>(</big><em>iterable</em><big>)</big><a class="headerlink" href="#mako.runtime.LoopContext" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
+<p>A magic loop variable.
+Automatically accessible in any <tt class="docutils literal"><span class="pre">%</span> <span class="pre">for</span></tt> block.</p>
+<p>See the section <a class="reference internal" href="#loop-context"><em>The Loop Context</em></a> for usage
+notes.</p>
+<dl class="docutils">
+<dt><tt class="xref py py-attr docutils literal"><span class="pre">parent</span></tt> -> <a class="reference internal" href="#mako.runtime.LoopContext" title="mako.runtime.LoopContext"><tt class="xref py py-class docutils literal"><span class="pre">LoopContext</span></tt></a> or <tt class="docutils literal"><span class="pre">None</span></tt></dt>
+<dd>The parent loop, if one exists.</dd>
+<dt><tt class="xref py py-attr docutils literal"><span class="pre">index</span></tt> -> <cite>int</cite></dt>
+<dd>The 0-based iteration count.</dd>
+<dt><tt class="xref py py-attr docutils literal"><span class="pre">reverse_index</span></tt> -> <cite>int</cite></dt>
+<dd>The number of iterations remaining.</dd>
+<dt><tt class="xref py py-attr docutils literal"><span class="pre">first</span></tt> -> <cite>bool</cite></dt>
+<dd><tt class="docutils literal"><span class="pre">True</span></tt> on the first iteration, <tt class="docutils literal"><span class="pre">False</span></tt> otherwise.</dd>
+<dt><tt class="xref py py-attr docutils literal"><span class="pre">last</span></tt> -> <cite>bool</cite></dt>
+<dd><tt class="docutils literal"><span class="pre">True</span></tt> on the last iteration, <tt class="docutils literal"><span class="pre">False</span></tt> otherwise.</dd>
+<dt><tt class="xref py py-attr docutils literal"><span class="pre">even</span></tt> -> <cite>bool</cite></dt>
+<dd><tt class="docutils literal"><span class="pre">True</span></tt> when <tt class="docutils literal"><span class="pre">index</span></tt> is even.</dd>
+<dt><tt class="xref py py-attr docutils literal"><span class="pre">odd</span></tt> -> <cite>bool</cite></dt>
+<dd><tt class="docutils literal"><span class="pre">True</span></tt> when <tt class="docutils literal"><span class="pre">index</span></tt> is odd.</dd>
+</dl>
+<dl class="method">
+<dt id="mako.runtime.LoopContext.cycle">
+<tt class="descname">cycle</tt><big>(</big><em>*values</em><big>)</big><a class="headerlink" href="#mako.runtime.LoopContext.cycle" title="Permalink to this definition">¶</a></dt>
+<dd><p>Cycle through values as the loop progresses.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="mako.runtime.Undefined">
+<em class="property">class </em><tt class="descclassname">mako.runtime.</tt><tt class="descname">Undefined</tt><a class="headerlink" href="#mako.runtime.Undefined" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
+<p>Represents an undefined value in a template.</p>
+<p>All template modules have a constant value
+<tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> present which is an instance of this
+object.</p>
+</dd></dl>
+
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Previous:
+        <a href="defs.html" title="previous chapter">Defs and Blocks</a>
+        Next:
+        <a href="namespaces.html" title="next chapter">Namespaces</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/search.html b/lib3/Mako-0.7.3/doc/search.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/search.html
@@ -0,0 +1,162 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+    Search
+ — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+        <script type="text/javascript" src="_static/searchtools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="#" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="#" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+    Search
+ 
+
+        <h2>
+            
+    Search
+
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+
+    <div id="docs-body" class="" >
+        
+
+
+
+
+
+<div id="searchform">
+<h3>Enter Search Terms:</h3>
+<form class="search" action="#" method="get">
+  <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+  <input type="hidden" name="check_keywords" value="yes" />
+  <input type="hidden" name="area" value="default" />
+</form>
+</div>
+
+<div id="search-results"></div>
+
+
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+    
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+    <script type="text/javascript" src="searchindex.js"></script>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/searchindex.js b/lib3/Mako-0.7.3/doc/searchindex.js
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/searchindex.js
@@ -0,0 +1,1 @@
+Search.setIndex({objects:{RichTraceback:{records:[8,0,1,""],reverse_traceback:[8,0,1,""],source:[8,0,1,""],lineno:[8,0,1,""],reverse_records:[8,0,1,""],error:[8,0,1,""],message:[8,0,1,""]},"mako.exceptions":{text_error_template:[8,3,1,""],RichTraceback:[8,2,1,""],html_error_template:[8,3,1,""]},"mako.lookup.TemplateLookup":{put_template:[8,1,1,""],get_template:[8,1,1,""],put_string:[8,1,1,""],adjust_uri:[8,1,1,""],filename_to_uri:[8,1,1,""]},"mako.runtime.Context":{write:[9,1,1,""],get:[9,1,1,""],keys:[9,1,1,""],push_caller:[9,1,1,""],writer:[9,1,1,""],pop_caller:[9,1,1,""],locals_:[9,1,1,""],lookup:[9,0,1,""],kwargs:[9,0,1,""]},"mako.lookup.TemplateCollection":{get_template:[8,1,1,""],adjust_uri:[8,1,1,""],has_template:[8,1,1,""],filename_to_uri:[8,1,1,""]},"mako.runtime.ModuleNamespace":{filename:[3,0,1,""]},"mako.cache.CacheImpl":{invalidate:[6,1,1,""],get_or_create:[6,1,1,""],pass_context:[6,0,1,""],set:[6,1,1,""],get:[6,1,1,""]},"mako.runtime.LoopContext":{cycle:[9,1,1,""]},"mako.cache":{register_plugin:[6,3,1,""],CacheImpl:[6,2,1,""],Cache:[6,2,1,""]},"mako.runtime.Namespace":{include_file:[3,1,1,""],template:[3,0,1,""],get_cached:[3,1,1,""],get_namespace:[3,1,1,""],cache:[3,0,1,""],uri:[3,0,1,""],module:[3,0,1,""],filename:[3,0,1,""],context:[3,0,1,""],get_template:[3,1,1,""],attr:[3,0,1,""]},"mako.lookup":{TemplateLookup:[8,2,1,""],TemplateCollection:[8,2,1,""]},"mako.runtime.TemplateNamespace":{uri:[3,0,1,""],module:[3,0,1,""],filename:[3,0,1,""]},"mako.runtime":{capture:[3,3,1,""],Undefined:[9,2,1,""],Namespace:[3,2,1,""],ModuleNamespace:[3,2,1,""],supports_caller:[3,3,1,""],Context:[9,2,1,""],LoopContext:[9,2,1,""],TemplateNamespace:[3,2,1,""]},"mako.ext.beaker_cache":{BeakerCacheImpl:[6,2,1,""]},"mako.cache.Cache":{invalidate:[6,1,1,""],set:[6,1,1,""],invalidate_body:[6,1,1,""],get:[6,1,1,""],invalidate_closure:[6,1,1,""],invalidate_def:[6,1,1,""],starttime:[6,0,1,""],put:[6,1,1,""],get_or_create:[6,1,1,""],id:[6,0,1,""],impl:[6,0,1,""]},"mako.template.Template":{render_context:[8,1,1,""],code:[8,0,1,""],render:[8,1,1,""],source:[8,0,1,""],render_unicode:[8,1,1,""],get_def:[8,1,1,""]},"mako.template":{DefTemplate:[8,2,1,""],Template:[8,2,1,""]}},terms:{interchang:4,four:[3,5],prefix:[6,9],dirnam:8,"_my_cache_work":6,typeerror:9,swap:6,under:[8,6,7],everi:[3,5],long_term:6,jack:8,voix:7,appar:[2,3],vast:7,pagearg:[0,9,3,7],get_templ:[8,6,3,7],buildtabl:0,cache_kei:6,direct:[0,8,6,3,5],batch:2,outputpath:8,second:[0,6,2],even:[5,9,7,4],"new":[0,8,9,6,4],ever:[3,7],metadata:5,widget:0,behavior:[8,2,9],here:[2,7,4,5,6,3,8,9],met:0,path:[8,6,3],interpret:[0,8,7],tagfilt:2,portabl:0,txt:[8,7,5],describ:[0,2,3,4,5,7,8,9],would:[0,2,4,6,7,8,9],call:[0,1,2,3,4,5,6,7,8,9],recommend:3,type:[0,5,6,7,8,9],until:8,relat:[8,6,7],notic:0,pkg_resourc:6,must:[0,8,6,3,7],join:7,setup:[8,6,4],work:[0,2,7,4,6,3,8,9],root:8,overrid:[7,4,6,3,8,9],give:[0,3],indic:[1,9,5],somefil:3,do_something_speci:6,want:[0,2,7,4,5,3,6,9],end:[5,2,4],quot:7,ordinari:3,output_encod:[8,7],how:[0,5,6,3,8,9],cheetah:7,updat:[8,9],module_filenam:8,recogn:[3,4],lai:0,after:[8,6,2,3,9],befor:[2,7,4,5,6,3,8],attempt:7,third:6,recompil:[8,6],maintain:[8,6],environ:[8,1,2,9,5],exclus:8,order:[8,6,5,7,4],origin:[2,7,6,3,8,9],somedata:0,over:[2,3,9],fall:6,becaus:[0,2,7,4],demarc:0,affect:9,flexibl:[5,2,4],myfil:5,streamlin:4,fix:[8,6,3],"__class__":8,better:[6,9],persist:6,easier:6,them:[0,2,4,3,8,9],thei:[0,2,4,5,7,8,9],safe:[9,7],default_filt:[8,2,7],jinja2:[0,5],html_error_templ:8,getvalu:[8,2],myghti:7,timeout:6,each:[0,4,5,6,7,8,9],side:[0,2,5],mean:[0,2,7,5,6,3,8,9],enorm:0,cacheimpl:[8,6],extract:8,expression_filt:2,unbound:8,goe:5,newli:6,content:[0,1,2,4,5,6,3,8,9],sane:0,mypackag:2,multilin:5,bottommost:4,free:3,standard:[6,7],argument:[0,1,2,3,5,6,7,8,9],traceback:8,moment:8,filter:[0,1,2,5,7,8,9],heck:[8,1,7],isn:9,text_error_templ:8,onto:[9,5],user:[8,6,9,7,5],rang:[0,5],render:[0,1,2,3,4,5,6,7,8,9],restrict:[0,4],unlik:7,alreadi:[8,9,4],wrapper:2,wasn:[9,4],agre:4,primari:8,lister:0,top:[0,2,4,3,6,9],sometim:[5,4],stack:[8,2,9],cache_region:6,too:[2,4],similarli:[0,7],john:0,consol:7,conson:9,namespac:[0,1,2,4,5,6,3,8,9],tool:6,setuptool:[8,6],somewhat:[0,2],some_namespac:3,myfilt:2,target:[0,2],keyword:[0,7,4,5,3,8,9],provid:[0,2,4,5,6,3,8,9],expr:[0,3],project:8,matter:4,minut:6,thu:8,mini:9,fashion:6,close:[0,8,3,5],runner:8,modern:6,htmlentityreplac:8,raw:[8,7],manner:2,templatelookup:[1,2,7,6,3,8,9],minu:6,latter:7,shall:4,usernam:[0,5],object:[0,2,3,4,5,6,7,8,9],regular:[0,1,2,3,4,5,7,8],phase:8,invalidate_closur:6,simplic:2,paradigm:4,don:[0,6,9,7,4],doc:[0,8,9,7,5],flow:5,doe:[0,7,4,5,3,9],declar:[0,1,2,4,5,3,8],tracelin:8,notion:9,opposit:4,"__str__":9,syntax:[0,1,2,8,5],get_resourc:5,involv:4,absolut:[0,7],layout:[0,8,4],acquir:[6,7],configur:[8,6,3,4],stop:[9,5],report:8,bar:[0,2,5,3,8,9],emb:[3,7,5],reload:8,short_term:6,black:9,elimin:7,result:[0,8,2,9,5],respons:[6,9,4],basemost:4,awar:[8,9,7],databas:0,urllib:2,implicit:[6,9],simplest:5,pybabel:8,awai:4,approach:[9,7,4],attribut:[0,1,2,4,5,6,3,8,9],preprocessor:8,easi:[2,9],howev:[0,6,3,7,4],against:[8,5],facet:9,logic:2,col:0,dogpil:6,guid:8,assum:[8,7],templatenamespac:3,three:[9,5],been:[8,6,2,3,7],accumul:5,much:[0,5,7,4],basic:[0,1,7,5,3,8],"__len__":9,quickli:7,disable_unicod:[8,2,7],ani:[0,2,3,4,5,6,7,8,9],multithread:6,lift:4,ident:8,servic:[6,7,5],properti:[8,3],calcul:8,printabl:7,kwarg:[8,6,9,3],somekei:6,sever:3,mako:[0,1,2,3,4,5,6,7,8,9],quand:7,perform:[8,2,3,7],make:[0,2,3,4,5,6,7,8,9],transpar:9,push_cal:9,complet:[8,3,4],rais:[0,8,9,7],caller_stack:[3,7],scenario:[0,8,9,3],get_cach:3,hypothet:4,inherit:[0,1,4,5,6,3,8,9],thi:[0,2,3,4,5,6,7,8,9],endif:[0,9,5],programm:7,everyth:9,pagecontrol:0,left:[8,2],identifi:[8,6],just:[0,2,3,4,5,7,8,9],invalidate_bodi:6,unbuff:2,yet:[6,3],languag:[0,7,5],previous:[8,3],enable_loop:[8,9],pygmentplugin:8,ham:9,ell:7,had:7,input_encod:[8,7],board:9,els:[8,6,9,5],gave:8,opt:[8,6],applic:[8,2,9,5],mayb:4,background:7,specif:[0,2,4,5,6,3,8,9],arbitrari:[6,5],manual:8,babelplugin:8,underli:[0,2,4,5,6,3,8,9],right:[0,2,9,7,5],old:9,deal:[9,7,5],excerpt:8,maxim:[6,7],percentag:8,intern:[8,6,2,7,9],subclass:[0,8,6],track:9,condit:[0,5,4],foo:[0,2,7,5,3,8,9],plu:8,bold:2,relationship:3,post:[0,8],"super":[6,3,7,4],plug:6,slightli:[3,7],surround:5,produc:[0,1,2,4,5,7,8,9],rudiment:[8,6],encod:[8,1,2,7],down:[6,7],lieu:8,wrap:[0,1,5,4],storag:7,accordingli:8,wai:[0,1,2,3,4,5,6,7,8,9],support:[0,7,5,6,3,8],transform:2,why:9,avail:[0,2,3,4,5,6,7,8,9],overhead:7,head:[0,8,4],form:[0,3,5],offer:[7,5],forc:8,get_def:[0,8,2],taken:[8,6,3],"true":[0,2,7,5,6,3,8,9],attr:[3,4],tell:5,emit:5,trim:[2,5],featur:[5,9,4],classic:[3,5],petit:7,"abstract":8,exist:[0,7,5,6,3,8,9],check:[8,5,9,7,4],when:[0,2,3,4,5,6,7,8,9],entrypoint:6,intend:[2,3],stringio:[8,9,7],intent:2,consid:[8,9],receiv:[0,2,3,5],faster:7,cache_en:[8,6],htdoc:8,ignor:[9,5],time:[0,1,2,4,6,8],push:9,serious:4,backward:6,concept:[0,8,5],chain:[5,9,3,4],skip:8,consum:[6,5],signific:[9,5],subcompon:0,row:0,decid:[9,5],middl:[5,2,4],depend:[8,5],mainlayout:[0,4],intermedi:4,decis:[9,7,4],sourc:[8,7,5],string:[2,7,5,6,3,8,9],word:[8,9,4],level:[0,1,2,3,4,5,6,7,8,9],did:4,iter:[0,9],item:[0,9,5],mycomp:6,quick:[0,5],lever:7,div:[0,8,3,4],dir:[8,6],slower:7,sign:5,namepacenam:0,appear:[2,9,5],current:[0,4,5,3,8,9],deriv:[6,2,7],gener:[0,2,3,4,5,6,7,8,9],address:[8,6],along:[6,3],toolbar:[5,4],bot:9,behav:0,commonli:[6,7,4],semant:[0,4],regardless:[0,9,4],extra:[5,4],modul:[0,1,2,3,4,5,6,7,8,9],prefer:7,render_bodi:[8,2,7,9],fake:5,marker:5,instal:6,callstack:9,memori:[8,6,5],sake:2,perl:5,live:6,handler:8,scope:[0,4,5,3,6,9],prep:9,chapter:[0,1,2,4,7,8],afford:8,accept:[2,7,5,6,3,8],render_:9,myexpress:2,mylookup:[8,7],fly:7,graphic:7,uniqu:[6,9,4],whatev:[8,9,3,7],purpos:[8,7],stream:[8,9,3,7,5],backslash:5,occur:[0,8,6],alwai:[0,9,7,4],differenti:9,multipl:[0,1,6,7,4],get:[2,7,4,5,6,3,8,9],modulenam:6,write:[2,7,5,6,3,8,9],pure:[3,7,5],cache_xyz:6,somevalu:6,map:8,product:8,usabl:0,mai:[2,7,5,6,3,8,9],data:[0,7,6,3,8,9],goal:2,practic:4,explicit:[0,7,5,3,6,9],format_except:8,inform:[8,3,7,5],"switch":9,preced:[8,5,3,7,4],combin:9,callabl:[0,2,5,6,3,8,9],extractor:8,still:[0,7,4],mainli:3,dynam:5,entiti:2,conjunct:8,group:[6,3],platform:8,jit:9,push_buff:2,main:[0,2,7,4,3,8,9],non:[8,9,7,5],recal:4,francoi:8,contriv:8,supersed:6,initi:0,underneath:6,therebi:3,now:[5,9,7,4],pop_fram:7,term:6,name:[0,1,2,3,4,5,6,7,8,9],drop:5,separ:[0,6,2,4],"__str":7,compil:[8,6,9,5],replac:[8,6,2,7],individu:[0,8,9,6],arg3:3,arg4:3,continu:[8,7,5],zebra:9,happen:[9,3,7],accomplish:[8,6],space:[0,6,5],intermix:4,correct:3,earlier:[6,7],migrat:[8,9],"byte":[8,7],care:[6,9,3,7],thing:[0,5,9,7,4],place:[0,8,5,6,4],think:9,first:[2,7,4,5,3,6,9],oper:[0,2,7,5,3,8,9],suspend:5,directli:[0,2,5,6,3,8],onc:[0,5,9,4],arrai:2,yourself:[8,7],walkthrough:0,textual:[8,2,4],custom:[0,2,7,5,6,3,8],open:[5,7,4],size:8,given:[0,2,4,6,3,8,9],silent:9,convent:0,caught:8,checker:9,necessarili:9,white:4,conveni:6,programat:8,copi:[9,3],specifi:[1,2,4,6,7,8,9],enclos:[0,9],mostli:[8,6,9,3],than:[2,4,5,7,6,9],serv:[8,7],"__m_local":7,were:[9,3,7],posit:3,seri:[8,6,7],pre:8,sai:[0,1,4,7,8,9],put_str:8,anywher:[0,5],deliv:[2,3],notimplementederror:8,techniqu:9,pop_cal:9,note:[0,2,7,4,6,3,8,9],take:[0,2,7,4,5,3],blunt:6,sure:5,trace:8,normal:[0,2,5,7,8,9],buffer:[1,2,7,5,3,8,9],subdef:0,synonym:[6,3],later:[6,5],highlight:8,templatenam:8,runtim:[1,2,4,5,6,3,8,9],preambl:8,shop:9,imaginez:7,delta:3,permiss:8,hack:9,xml:[8,2,5],onli:[0,2,4,5,6,7,8,9],explicitli:[8,9,3,7],state:[0,9,7],dict:7,overwritten:6,variou:[2,7,5,3,8,9],distinctli:4,dyn:3,tailor:0,requir:[0,6,3,7,5],where:[0,2,3,4,5,6,7,8,9],summari:5,wonder:5,nestabl:0,enumer:9,between:[0,9],"import":[0,2,7,5,6,3,8,9],across:[6,9],parent:[0,1,4,6,3,8,9],comp:3,cycl:9,my_dogpile_region:6,uncondition:7,come:[0,4,5,6,7,8],cache_url:[8,6],region:6,mani:[9,5],pow:5,pot:9,inspir:5,pop:[6,2,9],colon:[6,5],encoding_error:[8,7],ultim:[3,4],dessin:7,markedli:7,resolut:[8,3],those:[0,5,6,3,8,9],"case":[0,2,3,4,5,6,7,8,9],mouton:7,invok:[0,8,5,4],cannot:[0,8,7],invoc:4,advantag:[8,3,7,4],stdout:8,threadsaf:6,destin:8,shutil:8,ascii:7,"__init__":6,develop:7,author:9,same:[0,7,5,6,3,8,9],binari:7,epoch:6,html:[0,2,3,4,5,6,7,8],document:[8,6,5,7,4],breakdown:4,finish:4,utf8:[2,7],nest:[0,1,2,4,6,9],capabl:[8,6],vowel:9,improv:[8,7,5],extern:[0,6,4],moder:8,facad:6,without:[6,9,3,4],model:0,roughli:5,execut:[0,2,4,5,3,6,9],rest:[6,5,4],aspect:[7,5],speed:[2,7],versu:[8,3],except:[0,1,2,5,6,8,9],littl:[0,8,9],treatment:7,role:3,earli:[1,5],ream:7,around:[8,2,9],read:[9,7,5],moi:7,world:[0,7,5,3,8,9],use_pag:2,serve_templ:8,integ:[0,6,7],server:[8,6,5],either:[4,5,6,7,8,9],output:[0,1,2,3,4,5,7,8,9],manag:[6,9],somefunct:3,definit:[0,2,3,4],disait:7,inject:8,refer:[0,1,2,3,4,5,6,7,8,9],some_templ:8,power:5,garbag:6,pass_context:6,starttim:6,found:[0,9,5],"__name__":[8,6],"throw":[6,9],central:[0,2,9,5],act:[8,9],mytempl:[8,6,7],routin:8,overrod:4,strip:2,your:[0,2,4,5,3,9],msgstr:8,fast:8,her:7,area:[0,5,9,7,4],aren:[0,7],start:[0,6],compliant:7,interfac:6,lot:5,strictli:7,programmat:[0,1,2,7,6,9],tupl:8,regard:7,jut:9,illus:7,pull:[0,8,9,3],possibl:[0,6,2,9],"default":[0,2,3,4,5,6,7,8,9],unusu:8,embed:[0,8,9,3,5],creat:[0,7,5,6,3,8,9],multibyt:8,certain:[8,2,7],somedef:[0,6,2,3,5],intro:0,decreas:3,file:[0,1,3,4,5,6,7,8,9],again:[0,9],gettext:8,field:8,valid:5,you:[0,2,3,4,5,6,7,8,9],symbol:5,reduc:2,directori:[8,6,2,7,9],descript:8,mimic:8,potenti:4,escap:[0,1,2,7,5],represent:[8,5],all:[0,1,2,3,4,5,6,7,8,9],illustr:[8,2,4],scalar:3,abil:[8,6,7,5],follow:[0,4,5,3,8,9],program:[7,5],objnam:6,introduc:[0,5,9,3,4],sound:[5,4],"pla\u00eet":7,liter:[8,3,7],fals:[8,6,9],util:8,mechan:[6,5,4],failur:9,veri:[0,8,6,4],condition:3,list:[0,2,4,5,6,7,8,9],adjust:[8,3,5],small:8,pbj:9,aptli:8,design:2,nsname:5,pass:[0,7,4,5,6,3,8,9],further:5,what:[0,1,3,4,5,7,8,9],sub:[0,5],section:[0,4,6,3,8,9],advanc:8,abl:9,brief:8,version:[0,2,7,4,5,3,9],deepli:0,method:[0,1,2,3,4,5,6,7,8,9],contrast:[0,7,4],full:[8,5],themselv:[0,4,5,3,6,9],shouldn:9,inher:2,modifi:[0,8,7,4],valu:[0,2,7,5,6,3,8,9],search:[8,1],memcach:6,prior:[2,7,9],real:[8,5],render_mydef:9,via:[0,7,4,6,3,8,9],transit:9,ask:9,href:0,pythagorean:5,establish:[8,9],select:[7,4],mylib:5,distinct:8,regist:6,two:[0,2,3,4,5,6,7,8,9],push_fram:7,minor:8,more:[0,2,3,4,5,6,7,8,9],desir:[8,3,7],flag:[2,7,5,6,3,8,9],stick:[0,9,7,5],particular:[8,6,9,3,4],known:[0,3],cach:[0,1,2,5,6,3,8,9],none:[8,6,2,3,9],remain:[0,9],learn:7,def:[0,1,2,3,4,5,6,7,8,9],someobject:3,userbas:7,share:[0,9],templat:[0,1,2,3,4,5,6,7,8,9],sharp:0,wsgiutil:8,cours:9,newlin:[1,5],rather:9,anoth:[0,7,5,3,8,9],render_unicod:[8,7],simpl:[0,8,9,6,5],css:8,regener:8,resourc:[8,4],referenc:[0,9,3],variant:5,catalog:8,associ:[6,9],"short":6,footer:[5,4],confus:7,caus:[8,2,3,9],egg:9,help:[8,6,7],singleton:9,through:[8,9,7],paramet:[8,6,3,7],style:[0,7],might:[9,3,5],wouldn:[3,5],good:6,"return":[0,1,2,3,5,6,7,8,9],timestamp:6,framework:[8,1],ninja:4,achiev:[0,9,4],fulli:[8,2],unicod:[8,1,2,7],locals_:9,hard:[5,9,7,4],idea:[5,4],procedur:6,realli:7,expect:[0,5,7,4],beyond:[0,6],orient:[0,4],sometempl:6,lineno:8,print:[0,8,7],proxi:3,ast:7,guess:7,reason:[9,7],base:[1,2,4,5,6,3,8,9],put:[6,9,4],basi:[6,9],thrown:[8,6],thread:6,perhap:[0,9,5],assign:[0,8,9,5],major:[9,7],number:[0,8,9,6,5],done:[8,7],defnam:[0,5],blank:9,miss:[8,2,9],differ:[0,4,6,3,8,9],interact:[3,7],least:[8,3],calling_uri:3,statement:[0,8,5],natur:2,scheme:[0,8,9,7],store:[8,6,2,7,9],option:[7,5,6,3,8,9],modulenamespac:3,part:[6,9,3,4],pars:[8,7,5],kind:[2,4,5,6,7,8,9],whenev:[8,7,4],remot:[0,3],remov:[3,7],str:[8,2,7,9],arrang:5,toward:[0,4],grei:4,cleaner:9,mytmpl:8,get_namespac:3,comp2:3,packag:[6,5],comp1:3,expir:6,deftempl:[0,8],jour:7,built:[0,1,2,3,4,5,7,8,9],equival:[0,2,7,5,3,6],self:[0,4,5,6,3,8,9],undeclar:8,also:[0,2,3,4,5,6,7,8,9],build:[0,4],distribut:8,filesystem:[8,6,3],reach:[8,9],disgard:7,most:[0,7,4,5,6,3,8,9],plai:[3,7],jsp:5,ext:[8,6],fastencodingbuff:7,wsgi:8,particularli:3,find:[8,9,5],mydef:0,coerc:7,pretti:[7,5],writer:9,hit:[2,7],"__file__":3,express:[0,1,2,3,4,5,7,8,9],nativ:7,common:[8,1,7],set:[2,7,5,6,3,8,9],genshi:5,dump:[3,7],see:[0,7,5,6,3,8,9],dumb:7,arg:[0,2,5,6,3,8],reserv:9,whatsoev:7,someth:[0,2,7],topmost:[5,9,3,4],won:[8,9,4],altern:[8,9,7],signatur:[0,3],syntact:5,numer:5,popul:6,both:[0,2,4,7,8,9],last:[8,9],put_templ:8,alor:7,context:[0,1,2,3,5,6,7,8,9],whole:[0,2,3,4],load:[8,3,5],simpli:[2,4],bell:7,arbitrarili:0,header:[0,8,5,6,4],uniniti:9,param:5,suppli:[3,5],frobnizzl:5,throughout:3,backend:[6,3],empti:[2,7],accessor:[6,9,3,4],strategi:6,error_handl:8,imag:[8,7],great:[3,7],understand:7,func:3,xa9:7,look:[0,7,4,6,3,8,9],get_or_cr:6,straight:[8,7],histor:6,"while":[0,8,5,2,4],abov:[0,2,3,4,5,6,7,8,9],error:[0,8,9,7],anonym:[0,6,5],everyon:9,loop:[0,1,8,9,5],pylon:8,propag:[8,9,5],richtraceback:8,vou:7,itself:[0,2,3,4,5,6,7,8,9],decor:[1,2,3],minim:6,decod:[2,7],conflict:6,x80:7,wherea:[0,9,7,5],has_templ:8,stripe:9,pop_buff:2,typic:[8,6],recent:8,travers:3,task:6,older:0,cachemanag:6,entri:[8,6],somev:[9,3],elem:5,picki:7,endfor:[0,9,5],construct:[0,7,4,5,6,3,8],burden:7,sidebar:0,adjust_uri:8,msgid:8,theorem:5,input:[0,2,7],subsequ:6,format:[0,8,3,7,5],game:7,bit:[0,8,9],characterist:5,creation_funct:6,semi:6,whitespac:[0,2,5],resolv:8,collect:[8,6,9,3,7],"boolean":8,popular:8,encount:4,often:3,creation:[0,8,2,6],some:[0,2,3,4,5,6,7,8,9],back:[8,9,7,4],global:[0,6,9,3,4],understood:6,sampl:8,mirror:8,surpris:7,modulepath:6,though:[6,9,7,4],pep:7,per:[6,9,7,5],namespace_nam:3,substitut:[8,1,2,9,5],larg:4,slash:[3,5],leftmost:2,cgi:[2,7],buffer_filt:8,previou:[0,8,9,4],run:[8,9,3,7],namespacenam:[0,5],reverse_traceback:8,step:[0,8,7],loopcontext:9,from:[0,1,2,3,4,5,6,7,8,9],mynamespac:[3,5],exc_info:8,block:[0,1,2,4,5,6,9],within:[0,2,3,4,5,6,7,8,9],toplevelnotfound:8,ensur:[6,3,7],chang:[6,9,4],run_wsgi:8,span:[0,4],reverse_index:9,spam:9,bodi:[0,1,4,5,6,3,8,9],stylesheet:8,"long":[9,5],beaker_cach:6,includ:[0,5,6,3,8,9],suit:4,myfunc:5,properli:7,templatelookupexcept:8,link:8,translat:8,newer:[0,8],atom:8,line:[8,5,7,4],info:8,concaten:2,utf:[8,2,7],consist:5,caller:[0,2,3,9],my_tag:3,myescap:2,similar:[0,2,3,4,5,7,8,9],impl:6,constant:9,doesn:[0,9,3,4],repres:[0,5,6,7,8,9],modulename_cal:8,titl:[0,5,4],invalid:6,codec:[8,7],accountdata:0,draw:2,clean:[8,6],nightmar:7,bytestring_passthrough:8,xb4le:7,cache_typ:[8,6,5],depth:9,far:[8,5,7,4],hello:[0,8,3,7,5],code:[0,2,7,5,3,8,9],templatetext:[2,7],send:[2,7,4,3,8,9],sens:9,sent:[2,9,3,5],tri:[0,8,9],magic:[9,7],"try":[8,2,9,7,5],dealt:8,pleas:5,impli:8,cfg:8,odd:9,append:8,compat:[8,6,3],index:[1,4,5,3,8,9],compar:[8,7],xa9veil:7,access:[0,1,4,5,6,3,8,9],can:[0,2,3,4,5,6,7,8,9],len:5,closur:0,let:[0,8,9,4],becom:[8,3,7],sinc:[0,9,3,7,4],filesystem_check:8,convert:[8,6,7],convers:7,conceiv:9,ctx:8,implement:[0,8,6,4],appli:[0,2,7,5,3,8,9],approxim:8,mystuff:0,api:[1,2,6,3,8,9],immut:9,register_plugin:6,metaphor:4,commun:[0,9],next:[0,1,2,3,4,5,6,7,8,9],implic:7,few:9,trail:2,beakercacheimpl:6,account:0,retriev:6,augment:[0,1,4],obvious:4,control:[0,1,2,4,5,8,9],accountnam:0,process:[6,7,5],lock:6,slim:6,tag:[0,1,2,4,5,6,3,8,9],layoutdata:0,nari:7,instead:[0,2,7,4,3,8],templatecollect:8,overridden:[0,6,3,4],class_:4,tack:3,philosophi:9,callable_:[8,3],essenti:[6,3,7],correspond:[8,6,9,3,4],element:[0,8,9,7,5],issu:[0,8,7],allow:[0,2,3,4,5,6,7,8,9],elif:5,move:8,comma:[0,2],bunch:3,outer:0,chosen:6,myproj:8,bye:0,handl:[0,1,5,6,7,8,9],handi:3,"r\u00e9veill\u00e9":7,relativeto:8,somewher:[8,9,7],anyth:[0,7,4],nameerror:[8,9],mode:7,disregard:8,pygment:8,intellig:7,filehandl:7,our:[0,8,6,4],special:[8,6,2,9,5],out:[0,4,5,6,7,8],variabl:[0,4,5,3,8,9],contigu:5,categori:3,rel:[8,3],red:9,insid:[0,4,5,6,3,8],call_my_object:7,standalon:8,dictionari:[8,6,9,3],releas:[6,3,5],indent:5,xc3:7,could:4,lexer:[8,7,5],keep:0,outsid:[0,9,3,7,4],strict:8,system:[0,8,9,6,4],messag:[8,9],attach:3,"final":[2,7,4],cache_dir:[8,6],accompani:8,exactli:[0,4],filename_to_uri:8,structur:[1,9,5],charact:[8,7,5],simplecacheimpl:6,have:[0,2,3,4,5,6,7,8,9],tabl:[0,1,9],need:[0,7,4,6,3,8,9],turn:[2,7,4],babel:8,outward:8,builtin:7,best:5,which:[0,2,3,4,5,6,7,8,9],singl:[0,2,4,5,6,7,8],unless:[9,7],who:7,segment:7,"class":[0,7,4,6,3,8,9],url:[8,6,2,5],gather:7,request:[8,6,9],uri:[8,3,5],pipe:2,determin:[6,7],"_cach":6,fact:[0,7,4],render_context:8,dbm:6,text:[0,2,5,6,7,8,9],cache_timeout:[0,6],anywai:8,locat:[8,9,3,7],should:[8,6,9,3],suppos:[0,6],local:[0,2,5,6,3,8,9],meant:4,familiar:[0,5],bean:8,cache_:6,increas:8,cstringio:[8,7],enabl:[8,6,9,5],organ:[3,4],current_sect:5,stuff:[3,5],integr:[8,1,4],contain:[0,7,5,6,3,8],view:8,reverse_record:8,legaci:[8,9],collection_s:8,pinard:8,flip:0,bytestr:8,mako_modul:8,polymorph:5,correctli:9,pattern:8,written:[8,5,4],progress:9,neither:6,email:5,jot:9,kei:[8,6,9,3,7],module_directori:[8,6],tempfil:8,job:2,entir:[0,1,2,3,5,7,8],joe:5,cache_arg:[8,6],addit:[0,2,4,5,6,3,8],plugin:[6,1],etc:[0,8,9,6,5],instanc:[8,9,3,5],freeli:9,comment:[8,1,7,5],guidelin:6,mako_cach:6,respect:5,addition:[8,7,4],compon:[6,9,3],include_fil:3,treat:7,immedi:[8,5,9,7,4],upcom:6,togeth:4,present:[0,7,4,6,3,8,9],determinist:2,therefor:[8,5,3,4],plain:[0,8,3,7,5],contextu:0,defin:[0,1,2,3,4,5,6,7,8,9],helper:8,almost:[5,4],incom:7,revis:8,parti:6,began:9,member:[8,9,5],python:[0,1,2,3,4,5,7,8,9],denot:5,iou:9,upon:[0,8,2,6,4],effect:[0,6,2,3],distutil:8,markupsaf:[2,7],off:[0,6,2,3,4],mention:7,well:[0,2,3,4,5,6,7,8,9],exampl:[0,2,4,5,6,3,8,9],command:8,choos:7,undefin:[0,8,9,5],usual:[8,6,2,9,5],module_writ:8,less:[9,7,4],heavili:7,web:8,point:[0,7,4,5,6,3,8],add:[0,8,2,4],lookup:[8,6,9,7],dest:8,arguabl:7,cache_impl:[8,6],five:[6,5],know:[7,4],xe2:7,mkstemp:8,insert:4,like:[0,2,3,4,5,6,7,8,9],success:8,page:[0,1,2,4,5,6,3,8,9],unreach:0,exceed:9,revers:8,captur:[8,2,3,9],pariti:9,"export":[0,5,4],smoothli:4,proper:8,librari:[0,8,2,6,7],tmp:[8,2],lead:[2,3,9],usag:[0,1,2,3,4,6,7,8,9],nutshel:4,although:5,stage:8,beaker:[8,6],about:[8,1,5,9,4],actual:[0,2,4,5,6,3,8,9],column:0,htmlentitydef:2,discard:2,x99a:7,disabl:[1,2,6,7,8,9],own:[0,2,3,4,5,6,7,8,9],populate_self:3,automat:[0,2,4,5,6,8,9],"dr\u00f4le":7,leverag:5,quote_plu:2,inner:0,arg1:3,arg2:3,"function":[0,2,3,4,5,6,7,8,9],keyerror:9,invalidate_def:6,eas:[2,9],inlin:[5,9,4],buf:[8,2],wherev:7,count:[0,8,9],made:[6,9],whether:[2,9,5],wish:[6,2,9],displai:8,record:[8,3,5],below:[0,7,4],otherwis:[8,9,7,5],evalu:[0,3,5],"int":9,dure:[8,4],filenam:[8,6,3],twist:0,pit:9,probabl:[0,8,9,6],mutual:8,percent:5,detail:[0,4,5,7,8,9],other:[0,2,3,4,5,6,7,8,9],bool:9,futur:[3,5],varieti:[6,5],post_pros:0,supports_cal:3,templateuri:3,some_condit:0,stai:[6,9],experienc:9,strict_undefin:[8,9],rule:[0,7,4],portion:0},objtypes:{"0":"py:attribute","1":"py:method","2":"py:class","3":"py:function"},titles:["Defs and Blocks","Table of Contents","Filtering and Buffering","Namespaces","Inheritance","Syntax","Caching","The Unicode Chapter","Usage","The Mako Runtime Environment"],objnames:{"0":["py","attribute","Python attribute"],"1":["py","method","Python method"],"2":["py","class","Python class"],"3":["py","function","Python function"]},filenames:["defs","index","filtering","namespaces","inheritance","syntax","caching","unicode","usage","runtime"]})
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/doc/syntax.html b/lib3/Mako-0.7.3/doc/syntax.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/syntax.html
@@ -0,0 +1,596 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+                Syntax
+             — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+        <link rel="next" title="Defs and Blocks" href="defs.html" />
+        <link rel="prev" title="Usage" href="usage.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Prev:
+            <a href="usage.html" title="previous chapter">Usage</a>
+            </li>
+            <li>Next:
+            <a href="defs.html" title="next chapter">Defs and Blocks</a>
+            </li>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/syntax.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+                Syntax
+             
+
+        <h2>
+            
+                Syntax
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+    <div id="docs-sidebar">
+    <h3><a href="index.html">Table of Contents</a></h3>
+    <ul>
+<li><a class="reference internal" href="#">Syntax</a><ul>
+<li><a class="reference internal" href="#expression-substitution">Expression Substitution</a></li>
+<li><a class="reference internal" href="#expression-escaping">Expression Escaping</a></li>
+<li><a class="reference internal" href="#control-structures">Control Structures</a><ul>
+<li><a class="reference internal" href="#the-loop-context">The Loop Context</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#comments">Comments</a></li>
+<li><a class="reference internal" href="#newline-filters">Newline Filters</a></li>
+<li><a class="reference internal" href="#python-blocks">Python Blocks</a></li>
+<li><a class="reference internal" href="#module-level-blocks">Module-level Blocks</a></li>
+<li><a class="reference internal" href="#tags">Tags</a><ul>
+<li><a class="reference internal" href="#page"><tt class="docutils literal"><span class="pre"><%page></span></tt></a></li>
+<li><a class="reference internal" href="#include"><tt class="docutils literal"><span class="pre"><%include></span></tt></a></li>
+<li><a class="reference internal" href="#def"><tt class="docutils literal"><span class="pre"><%def></span></tt></a></li>
+<li><a class="reference internal" href="#block"><tt class="docutils literal"><span class="pre"><%block></span></tt></a></li>
+<li><a class="reference internal" href="#namespace"><tt class="docutils literal"><span class="pre"><%namespace></span></tt></a></li>
+<li><a class="reference internal" href="#inherit"><tt class="docutils literal"><span class="pre"><%inherit></span></tt></a></li>
+<li><a class="reference internal" href="#nsname-defname"><tt class="docutils literal"><span class="pre"><%</span></tt>nsname<tt class="docutils literal"><span class="pre">:</span></tt>defname<tt class="docutils literal"><span class="pre">></span></tt></a></li>
+<li><a class="reference internal" href="#call"><tt class="docutils literal"><span class="pre"><%call></span></tt></a></li>
+<li><a class="reference internal" href="#doc"><tt class="docutils literal"><span class="pre"><%doc></span></tt></a></li>
+<li><a class="reference internal" href="#text"><tt class="docutils literal"><span class="pre"><%text></span></tt></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#returning-early-from-a-template">Returning Early from a Template</a></li>
+</ul>
+</li>
+</ul>
+
+
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="usage.html" title="previous chapter">Usage</a>
+    </p>
+    <h4>Next Topic</h4>
+    <p>
+    <a href="defs.html" title="next chapter">Defs and Blocks</a>
+    </p>
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+
+    <div id="docs-body" class="withsidebar" >
+        
+<div class="section" id="syntax">
+<span id="syntax-toplevel"></span><h1>Syntax<a class="headerlink" href="#syntax" title="Permalink to this headline">¶</a></h1>
+<p>A Mako template is parsed from a text stream containing any kind
+of content, XML, HTML, email text, etc. The template can further
+contain Mako-specific directives which represent variable and/or
+expression substitutions, control structures (i.e. conditionals
+and loops), server-side comments, full blocks of Python code, as
+well as various tags that offer additional functionality. All of
+these constructs compile into real Python code. This means that
+you can leverage the full power of Python in almost every aspect
+of a Mako template.</p>
+<div class="section" id="expression-substitution">
+<h2>Expression Substitution<a class="headerlink" href="#expression-substitution" title="Permalink to this headline">¶</a></h2>
+<p>The simplest expression is just a variable substitution. The
+syntax for this is the <tt class="docutils literal"><span class="pre">${}</span></tt> construct, which is inspired by
+Perl, Genshi, JSP EL, and others:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x">this is x: </span><span class="cp">${</span><span class="n">x</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Above, the string representation of <tt class="docutils literal"><span class="pre">x</span></tt> is applied to the
+template’s output stream. If you’re wondering where <tt class="docutils literal"><span class="pre">x</span></tt> comes
+from, it’s usually from the <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> supplied to the
+template’s rendering function. If <tt class="docutils literal"><span class="pre">x</span></tt> was not supplied to the
+template and was not otherwise assigned locally, it evaluates to
+a special value <tt class="docutils literal"><span class="pre">UNDEFINED</span></tt>. More on that later.</p>
+<p>The contents within the <tt class="docutils literal"><span class="pre">${}</span></tt> tag are evaluated by Python
+directly, so full expressions are OK:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x">pythagorean theorem:  </span><span class="cp">${</span><span class="nb">pow</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nb">pow</span><span class="p">(</span><span class="n">y</span><span class="p">,</span><span class="mi">2</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The results of the expression are evaluated into a string result
+in all cases before being rendered to the output stream, such as
+the above example where the expression produces a numeric
+result.</p>
+</div>
+<div class="section" id="expression-escaping">
+<h2>Expression Escaping<a class="headerlink" href="#expression-escaping" title="Permalink to this headline">¶</a></h2>
+<p>Mako includes a number of built-in escaping mechanisms,
+including HTML, URI and XML escaping, as well as a “trim”
+function. These escapes can be added to an expression
+substitution using the <tt class="docutils literal"><span class="pre">|</span></tt> operator:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">"this is some text"</span> <span class="o">|</span> <span class="n">u</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The above expression applies URL escaping to the expression, and
+produces <tt class="docutils literal"><span class="pre">this+is+some+text</span></tt>. The <tt class="docutils literal"><span class="pre">u</span></tt> name indicates URL
+escaping, whereas <tt class="docutils literal"><span class="pre">h</span></tt> represents HTML escaping, <tt class="docutils literal"><span class="pre">x</span></tt>
+represents XML escaping, and <tt class="docutils literal"><span class="pre">trim</span></tt> applies a trim function.</p>
+<p>Read more about built-in filtering functions, including how to
+make your own filter functions, in <a class="reference internal" href="filtering.html"><em>Filtering and Buffering</em></a>.</p>
+</div>
+<div class="section" id="control-structures">
+<h2>Control Structures<a class="headerlink" href="#control-structures" title="Permalink to this headline">¶</a></h2>
+<p>A control structure refers to all those things that control the
+flow of a program – conditionals (i.e. <tt class="docutils literal"><span class="pre">if</span></tt>/<tt class="docutils literal"><span class="pre">else</span></tt>), loops (like
+<tt class="docutils literal"><span class="pre">while</span></tt> and <tt class="docutils literal"><span class="pre">for</span></tt>), as well as things like <tt class="docutils literal"><span class="pre">try</span></tt>/<tt class="docutils literal"><span class="pre">except</span></tt>. In Mako,
+control structures are written using the <tt class="docutils literal"><span class="pre">%</span></tt> marker followed
+by a regular Python control expression, and are “closed” by
+using another <tt class="docutils literal"><span class="pre">%</span></tt> marker with the tag “<tt class="docutils literal"><span class="pre">end<name></span></tt>”, where
+“<tt class="docutils literal"><span class="pre"><name></span></tt>” is the keyword of the expression:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">%</span> <span class="k">if</span> <span class="n">x</span><span class="o">==</span><span class="mi">5</span><span class="p">:</span><span class="x"></span>
+<span class="x">    this is some output</span>
+<span class="cp">%</span><span class="k"> endif</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre">%</span></tt> can appear anywhere on the line as long as no text
+precedes it; indentation is not significant. The full range of
+Python “colon” expressions are allowed here, including
+<tt class="docutils literal"><span class="pre">if</span></tt>/<tt class="docutils literal"><span class="pre">elif</span></tt>/<tt class="docutils literal"><span class="pre">else</span></tt>, <tt class="docutils literal"><span class="pre">while</span></tt>, <tt class="docutils literal"><span class="pre">for</span></tt>, and even <tt class="docutils literal"><span class="pre">def</span></tt>, although
+Mako has a built-in tag for defs which is more full-featured.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">%</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'one'</span><span class="p">,</span> <span class="s">'two'</span><span class="p">,</span> <span class="s">'three'</span><span class="p">,</span> <span class="s">'four'</span><span class="p">,</span> <span class="s">'five'</span><span class="p">]:</span><span class="x"></span>
+    <span class="cp">%</span> <span class="k">if</span> <span class="n">a</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s">'t'</span><span class="p">:</span><span class="x"></span>
+<span class="x">    its two or three</span>
+    <span class="cp">%</span> <span class="k">elif</span> <span class="n">a</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s">'f'</span><span class="p">:</span><span class="x"></span>
+<span class="x">    four/five</span>
+    <span class="cp">%</span> <span class="k">else</span><span class="p">:</span><span class="x"></span>
+<span class="x">    one</span>
+    <span class="cp">%</span><span class="k"> endif</span><span class="x"></span>
+<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre">%</span></tt> sign can also be “escaped”, if you actually want to
+emit a percent sign as the first non whitespace character on a
+line, by escaping it as in <tt class="docutils literal"><span class="pre">%%</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x">%% some text</span>
+
+<span class="x">    %% some more text</span>
+</pre></div>
+</div>
+<div class="section" id="the-loop-context">
+<h3>The Loop Context<a class="headerlink" href="#the-loop-context" title="Permalink to this headline">¶</a></h3>
+<p>The <strong>loop context</strong> provides additional information about a loop
+while inside of a <tt class="docutils literal"><span class="pre">%</span> <span class="pre">for</span></tt> structure:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><ul></span>
+<span class="cp">%</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="p">(</span><span class="s">"one"</span><span class="p">,</span> <span class="s">"two"</span><span class="p">,</span> <span class="s">"three"</span><span class="p">):</span><span class="x"></span>
+<span class="x">    <li>Item </span><span class="cp">${</span><span class="n">loop</span><span class="o">.</span><span class="n">index</span><span class="cp">}</span><span class="x">: </span><span class="cp">${</span><span class="n">a</span><span class="cp">}</span><span class="x"></li></span>
+<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+<span class="x"></ul></span>
+</pre></div>
+</div>
+<p>See <a class="reference internal" href="runtime.html#loop-context"><em>The Loop Context</em></a> for more information on this feature.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.7.</span></p>
+</div>
+</div>
+<div class="section" id="comments">
+<h2>Comments<a class="headerlink" href="#comments" title="Permalink to this headline">¶</a></h2>
+<p>Comments come in two varieties. The single line comment uses
+<tt class="docutils literal"><span class="pre">##</span></tt> as the first non-space characters on a line:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## this is a comment.</span><span class="x"></span>
+<span class="x">...text ...</span>
+</pre></div>
+</div>
+<p>A multiline version exists using <tt class="docutils literal"><span class="pre"><%doc></span> <span class="pre">...text...</span> <span class="pre"></%doc></span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%doc></span>
+<span class="cp">    these are comments</span>
+<span class="cp">    more comments</span>
+<span class="cp"></%doc></span><span class="x"></span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="newline-filters">
+<h2>Newline Filters<a class="headerlink" href="#newline-filters" title="Permalink to this headline">¶</a></h2>
+<p>The backslash (“<tt class="docutils literal"><span class="pre">\</span></tt>”) character, placed at the end of any
+line, will consume the newline character before continuing to
+the next line:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x">here is a line that goes onto </span><span class="o">\</span>
+<span class="x">another line.</span>
+</pre></div>
+</div>
+<p>The above text evaluates to:</p>
+<div class="highlight-text"><div class="highlight"><pre>here is a line that goes onto another line.
+</pre></div>
+</div>
+</div>
+<div class="section" id="python-blocks">
+<h2>Python Blocks<a class="headerlink" href="#python-blocks" title="Permalink to this headline">¶</a></h2>
+<p>Any arbitrary block of python can be dropped in using the <tt class="docutils literal"><span class="pre"><%</span>
+<span class="pre">%></span></tt> tags:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x">this is a template</span>
+<span class="cp"><%</span>
+    <span class="n">x</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">get_resource</span><span class="p">(</span><span class="s">'foo'</span><span class="p">)</span>
+    <span class="n">y</span> <span class="o">=</span> <span class="p">[</span><span class="n">z</span><span class="o">.</span><span class="n">element</span> <span class="k">for</span> <span class="n">z</span> <span class="ow">in</span> <span class="n">x</span> <span class="k">if</span> <span class="n">x</span><span class="o">.</span><span class="n">frobnizzle</span><span class="o">==</span><span class="mi">5</span><span class="p">]</span>
+<span class="cp">%></span>
+<span class="cp">%</span> <span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="n">y</span><span class="p">:</span><span class="x"></span>
+<span class="x">    element: </span><span class="cp">${</span><span class="n">elem</span><span class="cp">}</span>
+<span class="cp">%</span><span class="k"> endfor</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Within <tt class="docutils literal"><span class="pre"><%</span> <span class="pre">%></span></tt>, you’re writing a regular block of Python code.
+While the code can appear with an arbitrary level of preceding
+whitespace, it has to be consistently formatted with itself.
+Mako’s compiler will adjust the block of Python to be consistent
+with the surrounding generated Python code.</p>
+</div>
+<div class="section" id="module-level-blocks">
+<h2>Module-level Blocks<a class="headerlink" href="#module-level-blocks" title="Permalink to this headline">¶</a></h2>
+<p>A variant on <tt class="docutils literal"><span class="pre"><%</span> <span class="pre">%></span></tt> is the module-level code block, denoted
+by <tt class="docutils literal"><span class="pre"><%!</span> <span class="pre">%></span></tt>. Code within these tags is executed at the module
+level of the template, and not within the rendering function of
+the template. Therefore, this code does not have access to the
+template’s context and is only executed when the template is
+loaded into memory (which can be only once per application, or
+more, depending on the runtime environment). Use the <tt class="docutils literal"><span class="pre"><%!</span> <span class="pre">%></span></tt>
+tags to declare your template’s imports, as well as any
+pure-Python functions you might want to declare:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%!</span>
+    <span class="kn">import</span> <span class="nn">mylib</span>
+    <span class="kn">import</span> <span class="nn">re</span>
+
+    <span class="k">def</span> <span class="nf">filter</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
+        <span class="k">return</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="s">r'^@'</span><span class="p">,</span> <span class="s">''</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
+<span class="cp">%></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Any number of <tt class="docutils literal"><span class="pre"><%!</span> <span class="pre">%></span></tt> blocks can be declared anywhere in a
+template; they will be rendered in the resulting module
+in a single contiguous block above all render callables,
+in the order in which they appear in the source template.</p>
+</div>
+<div class="section" id="tags">
+<h2>Tags<a class="headerlink" href="#tags" title="Permalink to this headline">¶</a></h2>
+<p>The rest of what Mako offers takes place in the form of tags.
+All tags use the same syntax, which is similar to an XML tag
+except that the first character of the tag name is a <tt class="docutils literal"><span class="pre">%</span></tt>
+character. The tag is closed either by a contained slash
+character, or an explicit closing tag:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">include</span> <span class="na">file=</span><span class="s">"foo.txt"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"foo"</span> <span class="na">buffered=</span><span class="s">"True"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is a def</span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>All tags have a set of attributes which are defined for each
+tag. Some of these attributes are required. Also, many
+attributes support <strong>evaluation</strong>, meaning you can embed an
+expression (using <tt class="docutils literal"><span class="pre">${}</span></tt>) inside the attribute text:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">include</span> <span class="na">file=</span><span class="s">"/foo/bar/${myfile}.txt"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Whether or not an attribute accepts runtime evaluation depends
+on the type of tag and how that tag is compiled into the
+template. The best way to find out if you can stick an
+expression in is to try it! The lexer will tell you if it’s not
+valid.</p>
+<p>Heres a quick summary of all the tags:</p>
+<div class="section" id="page">
+<h3><tt class="docutils literal"><span class="pre"><%page></span></tt><a class="headerlink" href="#page" title="Permalink to this headline">¶</a></h3>
+<p>This tag defines general characteristics of the template,
+including caching arguments, and optional lists of arguments
+which the template expects when invoked.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">page</span> <span class="na">args=</span><span class="s">"x, y, z='default'"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Or a page tag that defines caching characteristics:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">page</span> <span class="na">cached=</span><span class="s">"True"</span> <span class="na">cache_type=</span><span class="s">"memory"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Currently, only one <tt class="docutils literal"><span class="pre"><%page></span></tt> tag gets used per template, the
+rest get ignored. While this will be improved in a future
+release, for now make sure you have only one <tt class="docutils literal"><span class="pre"><%page></span></tt> tag
+defined in your template, else you may not get the results you
+want. The details of what <tt class="docutils literal"><span class="pre"><%page></span></tt> is used for are described
+further in <a class="reference internal" href="namespaces.html#namespaces-body"><em>The body() Method</em></a> as well as <a class="reference internal" href="caching.html"><em>Caching</em></a>.</p>
+</div>
+<div class="section" id="include">
+<h3><tt class="docutils literal"><span class="pre"><%include></span></tt><a class="headerlink" href="#include" title="Permalink to this headline">¶</a></h3>
+<p>A tag that is familiar from other template languages, <tt class="docutils literal"><span class="pre">%include</span></tt>
+is a regular joe that just accepts a file argument and calls in
+the rendered result of that file:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">include</span> <span class="na">file=</span><span class="s">"header.html"</span><span class="cp">/></span><span class="x"></span>
+
+<span class="x">    hello world</span>
+
+<span class="cp"><%</span><span class="nb">include</span> <span class="na">file=</span><span class="s">"footer.html"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Include also accepts arguments which are available as <tt class="docutils literal"><span class="pre"><%page></span></tt> arguments in the receiving template:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">include</span> <span class="na">file=</span><span class="s">"toolbar.html"</span> <span class="na">args=</span><span class="s">"current_section='members', username='ed'"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="def">
+<h3><tt class="docutils literal"><span class="pre"><%def></span></tt><a class="headerlink" href="#def" title="Permalink to this headline">¶</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">%def</span></tt> tag defines a Python function which contains a set
+of content, that can be called at some other point in the
+template. The basic idea is simple:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"myfunc(x)"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is myfunc, x is </span><span class="cp">${</span><span class="n">x</span><span class="cp">}</span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+
+<span class="cp">${</span><span class="n">myfunc</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre">%def</span></tt> tag is a lot more powerful than a plain Python <tt class="docutils literal"><span class="pre">def</span></tt>, as
+the Mako compiler provides many extra services with <tt class="docutils literal"><span class="pre">%def</span></tt> that
+you wouldn’t normally have, such as the ability to export defs
+as template “methods”, automatic propagation of the current
+<a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>, buffering/filtering/caching flags, and def calls
+with content, which enable packages of defs to be sent as
+arguments to other def calls (not as hard as it sounds). Get the
+full deal on what <tt class="docutils literal"><span class="pre">%def</span></tt> can do in <a class="reference internal" href="defs.html"><em>Defs and Blocks</em></a>.</p>
+</div>
+<div class="section" id="block">
+<h3><tt class="docutils literal"><span class="pre"><%block></span></tt><a class="headerlink" href="#block" title="Permalink to this headline">¶</a></h3>
+<p><tt class="docutils literal"><span class="pre">%block</span></tt> is a tag that is close to a <tt class="docutils literal"><span class="pre">%def</span></tt>,
+except executes itself immediately in its base-most scope,
+and can also be anonymous (i.e. with no name):</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">block</span> <span class="na">filter=</span><span class="s">"h"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    some <html> stuff.</span>
+<span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Inspired by Jinja2 blocks, named blocks offer a syntactically pleasing way
+to do inheritance:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><html></span>
+<span class="x">    <body></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"header"</span><span class="cp">></span><span class="x"></span>
+<span class="x">        <h2></span><span class="cp"><%</span><span class="nb">block</span> <span class="na">name=</span><span class="s">"title"</span><span class="cp">/></span><span class="x"></h2></span>
+<span class="x">    </span><span class="cp"></%</span><span class="nb">block</span><span class="cp">></span><span class="x"></span>
+<span class="x">    </span><span class="cp">${</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">()</span><span class="cp">}</span><span class="x"></span>
+<span class="x">    </body></span>
+<span class="x"></html></span>
+</pre></div>
+</div>
+<p>Blocks are introduced in <a class="reference internal" href="defs.html#blocks"><em>Using Blocks</em></a> and further described in <a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.4.1.</span></p>
+</div>
+<div class="section" id="namespace">
+<h3><tt class="docutils literal"><span class="pre"><%namespace></span></tt><a class="headerlink" href="#namespace" title="Permalink to this headline">¶</a></h3>
+<p><tt class="docutils literal"><span class="pre">%namespace</span></tt> is Mako’s equivalent of Python’s <tt class="docutils literal"><span class="pre">import</span></tt>
+statement. It allows access to all the rendering functions and
+metadata of other template files, plain Python modules, as well
+as locally defined “packages” of functions.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">namespace</span> <span class="na">file=</span><span class="s">"functions.html"</span> <span class="na">import=</span><span class="s">"*"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>The underlying object generated by <tt class="docutils literal"><span class="pre">%namespace</span></tt>, an instance of
+<a class="reference internal" href="namespaces.html#mako.runtime.Namespace" title="mako.runtime.Namespace"><tt class="xref py py-class docutils literal"><span class="pre">mako.runtime.Namespace</span></tt></a>, is a central construct used in
+templates to reference template-specific information such as the
+current URI, inheritance structures, and other things that are
+not as hard as they sound right here. Namespaces are described
+in <a class="reference internal" href="namespaces.html"><em>Namespaces</em></a>.</p>
+</div>
+<div class="section" id="inherit">
+<h3><tt class="docutils literal"><span class="pre"><%inherit></span></tt><a class="headerlink" href="#inherit" title="Permalink to this headline">¶</a></h3>
+<p>Inherit allows templates to arrange themselves in <strong>inheritance
+chains</strong>. This is a concept familiar in many other template
+languages.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">inherit</span> <span class="na">file=</span><span class="s">"base.html"</span><span class="cp">/></span><span class="x"></span>
+</pre></div>
+</div>
+<p>When using the <tt class="docutils literal"><span class="pre">%inherit</span></tt> tag, control is passed to the topmost
+inherited template first, which then decides how to handle
+calling areas of content from its inheriting templates. Mako
+offers a lot of flexibility in this area, including dynamic
+inheritance, content wrapping, and polymorphic method calls.
+Check it out in <a class="reference internal" href="inheritance.html"><em>Inheritance</em></a>.</p>
+</div>
+<div class="section" id="nsname-defname">
+<h3><tt class="docutils literal"><span class="pre"><%</span></tt>nsname<tt class="docutils literal"><span class="pre">:</span></tt>defname<tt class="docutils literal"><span class="pre">></span></tt><a class="headerlink" href="#nsname-defname" title="Permalink to this headline">¶</a></h3>
+<p>Any user-defined “tag” can be created against
+a namespace by using a tag with a name of the form
+<tt class="docutils literal"><span class="pre"><%<namespacename>:<defname>></span></tt>. The closed and open formats of such a
+tag are equivalent to an inline expression and the <tt class="docutils literal"><span class="pre"><%call></span></tt>
+tag, respectively.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">mynamespace:somedef</span> <span class="na">param=</span><span class="s">"some value"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    this is the body</span>
+<span class="cp"></%</span><span class="nb">mynamespace:somedef</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+<p>To create custom tags which accept a body, see
+<a class="reference internal" href="defs.html#defs-with-content"><em>Calling a Def with Embedded Content and/or Other Defs</em></a>.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.2.3.</span></p>
+</div>
+<div class="section" id="call">
+<h3><tt class="docutils literal"><span class="pre"><%call></span></tt><a class="headerlink" href="#call" title="Permalink to this headline">¶</a></h3>
+<p>The call tag is the “classic” form of a user-defined tag, and is
+roughly equivalent to the <tt class="docutils literal"><span class="pre"><%namespacename:defname></span></tt> syntax
+described above. This tag is also described in <a class="reference internal" href="defs.html#defs-with-content"><em>Calling a Def with Embedded Content and/or Other Defs</em></a>.</p>
+</div>
+<div class="section" id="doc">
+<h3><tt class="docutils literal"><span class="pre"><%doc></span></tt><a class="headerlink" href="#doc" title="Permalink to this headline">¶</a></h3>
+<p>The <tt class="docutils literal"><span class="pre">%doc</span></tt> tag handles multiline comments:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%doc></span>
+<span class="cp">    these are comments</span>
+<span class="cp">    more comments</span>
+<span class="cp"></%doc></span><span class="x"></span>
+</pre></div>
+</div>
+<p>Also the <tt class="docutils literal"><span class="pre">##</span></tt> symbol as the first non-space characters on a line can be used for single line comments.</p>
+</div>
+<div class="section" id="text">
+<h3><tt class="docutils literal"><span class="pre"><%text></span></tt><a class="headerlink" href="#text" title="Permalink to this headline">¶</a></h3>
+<p>This tag suspends the Mako lexer’s normal parsing of Mako
+template directives, and returns its entire body contents as
+plain text. It is used pretty much to write documentation about
+Mako:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span><span class="nb">text</span> <span class="na">filter=</span><span class="s">"h"</span><span class="cp">></span><span class="x"></span>
+<span class="x">    heres some fake mako </span><span class="cp">${</span><span class="n">syntax</span><span class="cp">}</span><span class="x"></span>
+<span class="x">    </span><span class="cp"><%</span><span class="nb">def</span> <span class="na">name=</span><span class="s">"x()"</span><span class="cp">>${</span><span class="n">x</span><span class="cp">}</%</span><span class="nb">def</span><span class="cp">></span><span class="x"></span>
+<span class="cp"></%</span><span class="nb">text</span><span class="cp">></span><span class="x"></span>
+</pre></div>
+</div>
+</div>
+</div>
+<div class="section" id="returning-early-from-a-template">
+<h2>Returning Early from a Template<a class="headerlink" href="#returning-early-from-a-template" title="Permalink to this headline">¶</a></h2>
+<p>Sometimes you want to stop processing a template or <tt class="docutils literal"><span class="pre"><%def></span></tt>
+method in the middle and just use the text you’ve accumulated so
+far. You can use a <tt class="docutils literal"><span class="pre">return</span></tt> statement inside a Python
+block to do that.</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">%</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">len</span><span class="p">(</span><span class="n">records</span><span class="p">):</span><span class="x"></span>
+<span class="x">    No records found.</span>
+<span class="x">    </span><span class="cp"><%</span> <span class="k">return</span> <span class="cp">%></span>
+<span class="cp">%</span><span class="k"> endif</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Or perhaps:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp"><%</span>
+    <span class="k">if</span> <span class="ow">not</span> <span class="nb">len</span><span class="p">(</span><span class="n">records</span><span class="p">):</span>
+        <span class="k">return</span>
+<span class="cp">%></span><span class="x"></span>
+</pre></div>
+</div>
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Previous:
+        <a href="usage.html" title="previous chapter">Usage</a>
+        Next:
+        <a href="defs.html" title="next chapter">Defs and Blocks</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/unicode.html b/lib3/Mako-0.7.3/doc/unicode.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/unicode.html
@@ -0,0 +1,476 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+                The Unicode Chapter
+             — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+        <link rel="next" title="Caching" href="caching.html" />
+        <link rel="prev" title="Filtering and Buffering" href="filtering.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Prev:
+            <a href="filtering.html" title="previous chapter">Filtering and Buffering</a>
+            </li>
+            <li>Next:
+            <a href="caching.html" title="next chapter">Caching</a>
+            </li>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/unicode.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+                The Unicode Chapter
+             
+
+        <h2>
+            
+                The Unicode Chapter
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+    <div id="docs-sidebar">
+    <h3><a href="index.html">Table of Contents</a></h3>
+    <ul>
+<li><a class="reference internal" href="#">The Unicode Chapter</a><ul>
+<li><a class="reference internal" href="#specifying-the-encoding-of-a-template-file">Specifying the Encoding of a Template File</a></li>
+<li><a class="reference internal" href="#handling-expressions">Handling Expressions</a></li>
+<li><a class="reference internal" href="#defining-output-encoding">Defining Output Encoding</a><ul>
+<li><a class="reference internal" href="#buffer-selection">Buffer Selection</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#saying-to-heck-with-it-disabling-the-usage-of-unicode-entirely">Saying to Heck with It: Disabling the Usage of Unicode Entirely</a><ul>
+<li><a class="reference internal" href="#rules-for-using-disable-unicode-true">Rules for using <tt class="docutils literal"><span class="pre">disable_unicode=True</span></tt></a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+
+
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="filtering.html" title="previous chapter">Filtering and Buffering</a>
+    </p>
+    <h4>Next Topic</h4>
+    <p>
+    <a href="caching.html" title="next chapter">Caching</a>
+    </p>
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+
+    <div id="docs-body" class="withsidebar" >
+        
+<div class="section" id="the-unicode-chapter">
+<span id="unicode-toplevel"></span><h1>The Unicode Chapter<a class="headerlink" href="#the-unicode-chapter" title="Permalink to this headline">¶</a></h1>
+<p>The Python language supports two ways of representing what we
+know as “strings”, i.e. series of characters. In Python 2, the
+two types are <tt class="docutils literal"><span class="pre">string</span></tt> and <tt class="docutils literal"><span class="pre">unicode</span></tt>, and in Python 3 they are
+<tt class="docutils literal"><span class="pre">bytes</span></tt> and <tt class="docutils literal"><span class="pre">string</span></tt>. A key aspect of the Python 2 <tt class="docutils literal"><span class="pre">string</span></tt> and
+Python 3 <tt class="docutils literal"><span class="pre">bytes</span></tt> types are that they contain no information
+regarding what <strong>encoding</strong> the data is stored in. For this
+reason they were commonly referred to as <strong>byte strings</strong> on
+Python 2, and Python 3 makes this name more explicit. The
+origins of this come from Python’s background of being developed
+before the Unicode standard was even available, back when
+strings were C-style strings and were just that, a series of
+bytes. Strings that had only values below 128 just happened to
+be <strong>ASCII</strong> strings and were printable on the console, whereas
+strings with values above 128 would produce all kinds of
+graphical characters and bells.</p>
+<p>Contrast the “byte-string” type with the “unicode/string” type.
+Objects of this latter type are created whenever you say something like
+<tt class="docutils literal"><span class="pre">u"hello</span> <span class="pre">world"</span></tt> (or in Python 3, just <tt class="docutils literal"><span class="pre">"hello</span> <span class="pre">world"</span></tt>). In this
+case, Python represents each character in the string internally
+using multiple bytes per character (something similar to
+UTF-16). What’s important is that when using the
+<tt class="docutils literal"><span class="pre">unicode</span></tt>/<tt class="docutils literal"><span class="pre">string</span></tt> type to store strings, Python knows the
+data’s encoding; it’s in its own internal format. Whereas when
+using the <tt class="docutils literal"><span class="pre">string</span></tt>/<tt class="docutils literal"><span class="pre">bytes</span></tt> type, it does not.</p>
+<p>When Python 2 attempts to treat a byte-string as a string, which
+means it’s attempting to compare/parse its characters, to coerce
+it into another encoding, or to decode it to a unicode object,
+it has to guess what the encoding is. In this case, it will
+pretty much always guess the encoding as <tt class="docutils literal"><span class="pre">ascii</span></tt>... and if the
+byte-string contains bytes above value 128, you’ll get an error.
+Python 3 eliminates much of this confusion by just raising an
+error unconditionally if a byte-string is used in a
+character-aware context.</p>
+<p>There is one operation that Python <em>can</em> do with a non-ASCII
+byte-string, and it’s a great source of confusion: it can dump the
+byte-string straight out to a stream or a file, with nary a care
+what the encoding is. To Python, this is pretty much like
+dumping any other kind of binary data (like an image) to a
+stream somewhere. In Python 2, it is common to see programs that
+embed all kinds of international characters and encodings into
+plain byte-strings (i.e. using <tt class="docutils literal"><span class="pre">"hello</span> <span class="pre">world"</span></tt> style literals)
+can fly right through their run, sending reams of strings out to
+wherever they are going, and the programmer, seeing the same
+output as was expressed in the input, is now under the illusion
+that his or her program is Unicode-compliant. In fact, their
+program has no unicode awareness whatsoever, and similarly has
+no ability to interact with libraries that <em>are</em> unicode aware.
+Python 3 makes this much less likely by defaulting to unicode as
+the storage format for strings.</p>
+<p>The “pass through encoded data” scheme is what template
+languages like Cheetah and earlier versions of Myghty do by
+default. Mako as of version 0.2 also supports this mode of
+operation when using Python 2, using the <tt class="docutils literal"><span class="pre">disable_unicode=True</span></tt>
+flag. However, when using Mako in its default mode of
+unicode-aware, it requires explicitness when dealing with
+non-ASCII encodings. Additionally, if you ever need to handle
+unicode strings and other kinds of encoding conversions more
+intelligently, the usage of raw byte-strings quickly becomes a
+nightmare, since you are sending the Python interpreter
+collections of bytes for which it can make no intelligent
+decisions with regards to encoding. In Python 3 Mako only allows
+usage of native, unicode strings.</p>
+<p>In normal Mako operation, all parsed template constructs and
+output streams are handled internally as Python <tt class="docutils literal"><span class="pre">unicode</span></tt>
+objects. It’s only at the point of <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a> that this unicode
+stream may be rendered into whatever the desired output encoding
+is. The implication here is that the template developer must
+:ensure that <a class="reference internal" href="#set-template-file-encoding"><em>the encoding of all non-ASCII templates is explicit</em></a> (still required in Python 3),
+that <a class="reference internal" href="#handling-non-ascii-expressions"><em>all non-ASCII-encoded expressions are in one way or another
+converted to unicode</em></a>
+(not much of a burden in Python 3), and that <a class="reference internal" href="#defining-output-encoding"><em>the output stream of the
+template is handled as a unicode stream being encoded to some
+encoding</em></a> (still required in Python 3).</p>
+<div class="section" id="specifying-the-encoding-of-a-template-file">
+<span id="set-template-file-encoding"></span><h2>Specifying the Encoding of a Template File<a class="headerlink" href="#specifying-the-encoding-of-a-template-file" title="Permalink to this headline">¶</a></h2>
+<p>This is the most basic encoding-related setting, and it is
+equivalent to Python’s “magic encoding comment”, as described in
+<a class="reference external" href="http://www.python.org/dev/peps/pep-0263/">pep-0263</a>. Any
+template that contains non-ASCII characters requires that this
+comment be present so that Mako can decode to unicode (and also
+make usage of Python’s AST parsing services). Mako’s lexer will
+use this encoding in order to convert the template source into a
+<tt class="docutils literal"><span class="pre">unicode</span></tt> object before continuing its parsing:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">## -*- coding: utf-8 -*-</span><span class="x"></span>
+
+<span class="x">Alors vous imaginez ma surprise, au lever du jour, quand</span>
+<span class="x">une drôle de petite voix m’a réveillé. Elle disait:</span>
+<span class="x"> « S’il vous plaît… dessine-moi un mouton! »</span>
+</pre></div>
+</div>
+<p>For the picky, the regular expression used is derived from that
+of the above mentioned pep:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="c">#.*coding[:=]\s*([-\w.]+).*\n</span>
+</pre></div>
+</div>
+<p>The lexer will convert to unicode in all cases, so that if any
+characters exist in the template that are outside of the
+specified encoding (or the default of <tt class="docutils literal"><span class="pre">ascii</span></tt>), the error will
+be immediate.</p>
+<p>As an alternative, the template encoding can be specified
+programmatically to either <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> or <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> via
+the <tt class="docutils literal"><span class="pre">input_encoding</span></tt> parameter:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">t</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'./'</span><span class="p">],</span> <span class="n">input_encoding</span><span class="o">=</span><span class="s">'utf-8'</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>The above will assume all located templates specify <tt class="docutils literal"><span class="pre">utf-8</span></tt>
+encoding, unless the template itself contains its own magic
+encoding comment, which takes precedence.</p>
+</div>
+<div class="section" id="handling-expressions">
+<span id="handling-non-ascii-expressions"></span><h2>Handling Expressions<a class="headerlink" href="#handling-expressions" title="Permalink to this headline">¶</a></h2>
+<p>The next area that encoding comes into play is in expression
+constructs. By default, Mako’s treatment of an expression like
+this:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">"hello world"</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>looks something like this:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">unicode</span><span class="p">(</span><span class="s">"hello world"</span><span class="p">))</span>
+</pre></div>
+</div>
+<p>In Python 3, it’s just:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="s">"hello world"</span><span class="p">))</span>
+</pre></div>
+</div>
+<p>That is, <strong>the output of all expressions is run through the
+``unicode`` built-in</strong>. This is the default setting, and can be
+modified to expect various encodings. The <tt class="docutils literal"><span class="pre">unicode</span></tt> step serves
+both the purpose of rendering non-string expressions into
+strings (such as integers or objects which contain <tt class="docutils literal"><span class="pre">__str()__</span></tt>
+methods), and to ensure that the final output stream is
+constructed as a unicode object. The main implication of this is
+that <strong>any raw byte-strings that contain an encoding other than
+ASCII must first be decoded to a Python unicode object</strong>. It
+means you can’t say this in Python 2:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">"voix m’a réveillé."</span><span class="cp">}</span>  <span class="cp">## error in Python 2!</span><span class="x"></span>
+</pre></div>
+</div>
+<p>You must instead say this:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="s">u"voix m’a réveillé."</span><span class="cp">}</span>  <span class="cp">## OK !</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Similarly, if you are reading data from a file that is streaming
+bytes, or returning data from some object that is returning a
+Python byte-string containing a non-ASCII encoding, you have to
+explicitly decode to unicode first, such as:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="cp">${</span><span class="n">call_my_object</span><span class="p">()</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+</pre></div>
+</div>
+<p>Note that filehandles acquired by <tt class="docutils literal"><span class="pre">open()</span></tt> in Python 3 default
+to returning “text”, that is the decoding is done for you. See
+Python 3’s documentation for the <tt class="docutils literal"><span class="pre">open()</span></tt> built-in for details on
+this.</p>
+<p>If you want a certain encoding applied to <em>all</em> expressions,
+override the <tt class="docutils literal"><span class="pre">unicode</span></tt> builtin with the <tt class="docutils literal"><span class="pre">decode</span></tt> built-in at the
+<a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> or <a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> level:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">templatetext</span><span class="p">,</span> <span class="n">default_filters</span><span class="o">=</span><span class="p">[</span><span class="s">'decode.utf8'</span><span class="p">])</span>
+</pre></div>
+</div>
+<p>Note that the built-in <tt class="docutils literal"><span class="pre">decode</span></tt> object is slower than the
+<tt class="docutils literal"><span class="pre">unicode</span></tt> function, since unlike <tt class="docutils literal"><span class="pre">unicode</span></tt> it’s not a Python
+built-in, and it also checks the type of the incoming data to
+determine if string conversion is needed first.</p>
+<p>The <tt class="docutils literal"><span class="pre">default_filters</span></tt> argument can be used to entirely customize
+the filtering process of expressions. This argument is described
+in <a class="reference internal" href="filtering.html#filtering-default-filters"><em>The default_filters Argument</em></a>.</p>
+</div>
+<div class="section" id="defining-output-encoding">
+<span id="id1"></span><h2>Defining Output Encoding<a class="headerlink" href="#defining-output-encoding" title="Permalink to this headline">¶</a></h2>
+<p>Now that we have a template which produces a pure unicode output
+stream, all the hard work is done. We can take the output and do
+anything with it.</p>
+<p>As stated in the <a class="reference internal" href="usage.html"><em>“Usage” chapter</em></a>, both <a class="reference internal" href="usage.html#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> and
+<a class="reference internal" href="usage.html#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> accept <tt class="docutils literal"><span class="pre">output_encoding</span></tt> and <tt class="docutils literal"><span class="pre">encoding_errors</span></tt>
+parameters which can be used to encode the output in any Python
+supported codec:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+<span class="kn">from</span> <span class="nn">mako.lookup</span> <span class="kn">import</span> <span class="n">TemplateLookup</span>
+
+<span class="n">mylookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/docs'</span><span class="p">],</span> <span class="n">output_encoding</span><span class="o">=</span><span class="s">'utf-8'</span><span class="p">,</span> <span class="n">encoding_errors</span><span class="o">=</span><span class="s">'replace'</span><span class="p">)</span>
+
+<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">mylookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">"foo.txt"</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+</pre></div>
+</div>
+<p><a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a> will return a <tt class="docutils literal"><span class="pre">bytes</span></tt> object in Python 3 if an output
+encoding is specified. By default it performs no encoding and
+returns a native string.</p>
+<p><a class="reference internal" href="usage.html#mako.template.Template.render_unicode" title="mako.template.Template.render_unicode"><tt class="xref py py-meth docutils literal"><span class="pre">render_unicode()</span></tt></a> will return the template output as a Python
+<tt class="docutils literal"><span class="pre">unicode</span></tt> object (or <tt class="docutils literal"><span class="pre">string</span></tt> in Python 3):</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>The above method disgards the output encoding keyword argument;
+you can encode yourself by saying:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">,</span> <span class="s">'replace'</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="section" id="buffer-selection">
+<h3>Buffer Selection<a class="headerlink" href="#buffer-selection" title="Permalink to this headline">¶</a></h3>
+<p>Mako does play some games with the style of buffering used
+internally, to maximize performance. Since the buffer is by far
+the most heavily used object in a render operation, it’s
+important!</p>
+<p>When calling <a class="reference internal" href="usage.html#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a> on a template that does not specify any
+output encoding (i.e. it’s <tt class="docutils literal"><span class="pre">ascii</span></tt>), Python’s <tt class="docutils literal"><span class="pre">cStringIO</span></tt> module,
+which cannot handle encoding of non-ASCII <tt class="docutils literal"><span class="pre">unicode</span></tt> objects
+(even though it can send raw byte-strings through), is used for
+buffering. Otherwise, a custom Mako class called
+<tt class="docutils literal"><span class="pre">FastEncodingBuffer</span></tt> is used, which essentially is a super
+dumbed-down version of <tt class="docutils literal"><span class="pre">StringIO</span></tt> that gathers all strings into
+a list and uses <tt class="docutils literal"><span class="pre">u''.join(elements)</span></tt> to produce the final output
+– it’s markedly faster than <tt class="docutils literal"><span class="pre">StringIO</span></tt>.</p>
+</div>
+</div>
+<div class="section" id="saying-to-heck-with-it-disabling-the-usage-of-unicode-entirely">
+<span id="unicode-disabled"></span><h2>Saying to Heck with It: Disabling the Usage of Unicode Entirely<a class="headerlink" href="#saying-to-heck-with-it-disabling-the-usage-of-unicode-entirely" title="Permalink to this headline">¶</a></h2>
+<p>Some segments of Mako’s userbase choose to make no usage of
+Unicode whatsoever, and instead would prefer the “pass through”
+approach; all string expressions in their templates return
+encoded byte-strings, and they would like these strings to pass
+right through. The only advantage to this approach is that
+templates need not use <tt class="docutils literal"><span class="pre">u""</span></tt> for literal strings; there’s an
+arguable speed improvement as well since raw byte-strings
+generally perform slightly faster than unicode objects in
+Python. For these users, assuming they’re sticking with Python
+2, they can hit the <tt class="docutils literal"><span class="pre">disable_unicode=True</span></tt> flag as so:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="c"># -*- encoding:utf-8 -*-</span>
+<span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+
+<span class="n">t</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s">"drôle de petite voix m’a réveillé."</span><span class="p">,</span> <span class="n">disable_unicode</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> <span class="n">input_encoding</span><span class="o">=</span><span class="s">'utf-8'</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">t</span><span class="o">.</span><span class="n">code</span>
+</pre></div>
+</div>
+<p>The <tt class="docutils literal"><span class="pre">disable_unicode</span></tt> mode is strictly a Python 2 thing. It is
+not supported at all in Python 3.</p>
+<p>The generated module source code will contain elements like
+these:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="c"># -*- encoding:utf-8 -*-</span>
+<span class="c">#  ...more generated code ...</span>
+
+<span class="k">def</span> <span class="nf">render_body</span><span class="p">(</span><span class="n">context</span><span class="p">,</span><span class="o">**</span><span class="n">pageargs</span><span class="p">):</span>
+    <span class="n">context</span><span class="o">.</span><span class="n">caller_stack</span><span class="o">.</span><span class="n">push_frame</span><span class="p">()</span>
+    <span class="k">try</span><span class="p">:</span>
+        <span class="n">__M_locals</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">pageargs</span><span class="o">=</span><span class="n">pageargs</span><span class="p">)</span>
+        <span class="c"># SOURCE LINE 1</span>
+        <span class="n">context</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'dr</span><span class="se">\xc3\xb4</span><span class="s">le de petite voix m</span><span class="se">\xe2\x80\x99</span><span class="s">a r</span><span class="se">\xc3\xa9</span><span class="s">veill</span><span class="se">\xc3\xa9</span><span class="s">.'</span><span class="p">)</span>
+        <span class="k">return</span> <span class="s">''</span>
+    <span class="k">finally</span><span class="p">:</span>
+        <span class="n">context</span><span class="o">.</span><span class="n">caller_stack</span><span class="o">.</span><span class="n">pop_frame</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>Where above that the string literal used within <a class="reference internal" href="runtime.html#mako.runtime.Context.write" title="mako.runtime.Context.write"><tt class="xref py py-meth docutils literal"><span class="pre">Context.write()</span></tt></a>
+is a regular byte-string.</p>
+<p>When <tt class="docutils literal"><span class="pre">disable_unicode=True</span></tt> is turned on, the <tt class="docutils literal"><span class="pre">default_filters</span></tt>
+argument which normally defaults to <tt class="docutils literal"><span class="pre">["unicode"]</span></tt> now defaults
+to <tt class="docutils literal"><span class="pre">["str"]</span></tt> instead. Setting <tt class="docutils literal"><span class="pre">default_filters</span></tt> to the empty list
+<tt class="docutils literal"><span class="pre">[]</span></tt> can remove the overhead of the <tt class="docutils literal"><span class="pre">str</span></tt> call. Also, in this
+mode you <strong>cannot</strong> safely call <a class="reference internal" href="usage.html#mako.template.Template.render_unicode" title="mako.template.Template.render_unicode"><tt class="xref py py-meth docutils literal"><span class="pre">render_unicode()</span></tt></a> – you’ll get
+unicode/decode errors.</p>
+<p>The <tt class="docutils literal"><span class="pre">h</span></tt> filter (HTML escape) uses a less performant pure Python
+escape function in non-unicode mode. This because
+MarkupSafe only supports Python unicode objects for non-ASCII
+strings.</p>
+<p class="versionchanged">
+<span class="versionmodified">Changed in version 0.3.4: </span>In prior versions, it used <tt class="docutils literal"><span class="pre">cgi.escape()</span></tt>, which has been replaced
+with a function that also escapes single quotes.</p>
+<div class="section" id="rules-for-using-disable-unicode-true">
+<h3>Rules for using <tt class="docutils literal"><span class="pre">disable_unicode=True</span></tt><a class="headerlink" href="#rules-for-using-disable-unicode-true" title="Permalink to this headline">¶</a></h3>
+<ul class="simple">
+<li>Don’t use this mode unless you really, really want to and you
+absolutely understand what you’re doing.</li>
+<li>Don’t use this option just because you don’t want to learn to
+use Unicode properly; we aren’t supporting user issues in this
+mode of operation. We will however offer generous help for the
+vast majority of users who stick to the Unicode program.</li>
+<li>Python 3 is unicode by default, and the flag is not available
+when running on Python 3.</li>
+</ul>
+</div>
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Previous:
+        <a href="filtering.html" title="previous chapter">Filtering and Buffering</a>
+        Next:
+        <a href="caching.html" title="next chapter">Caching</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/doc/usage.html b/lib3/Mako-0.7.3/doc/usage.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/doc/usage.html
@@ -0,0 +1,1057 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+<head>
+<title>
+    
+                Usage
+             — 
+    Mako 0.7.3 Documentation
+</title>
+
+    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+    <link rel="stylesheet" href="_static/docs.css" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '#',
+          VERSION:     '0.7.3',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '.html'
+      };
+    </script>
+        <script type="text/javascript" src="_static/jquery.js"></script>
+        <script type="text/javascript" src="_static/underscore.js"></script>
+        <script type="text/javascript" src="_static/doctools.js"></script>
+    <link rel="index" title="Index" href="genindex.html" />
+    <link rel="search" title="Search" href="search.html" />
+    <link rel="top" title="Mako 0.7.3 Documentation" href="index.html" />
+        <link rel="next" title="Syntax" href="syntax.html" />
+        <link rel="prev" title="Table of Contents" href="index.html" />
+
+<link rel="stylesheet" href="_static/site.css"></link>
+
+
+</head>
+<body>
+    <div id="wrap">
+    <div class="rightbar">
+
+
+    <div class="slogan">
+    Hyperfast and lightweight templating for the Python platform.
+    </div>
+
+
+    </div>
+
+    <a href="http://www.makotemplates.org/"><img src="_static/makoLogo.png" /></a>
+
+    <hr/>
+
+    
+
+
+
+
+
+
+
+
+
+<div id="docs-container">
+
+
+
+<div id="docs-header">
+    <h1>Mako 0.7.3 Documentation</h1>
+
+    <div id="docs-search">
+    Search:
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </div>
+
+    <div id="docs-version-header">
+        Release: <span class="version-num">0.7.3</span>
+
+    </div>
+
+</div>
+
+<div id="docs-top-navigation">
+    <div id="docs-top-page-control" class="docs-navigation-links">
+        <ul>
+            <li>Prev:
+            <a href="index.html" title="previous chapter">Table of Contents</a>
+            </li>
+            <li>Next:
+            <a href="syntax.html" title="next chapter">Syntax</a>
+            </li>
+
+        <li>
+            <a href="index.html">Table of Contents</a> |
+            <a href="genindex.html">Index</a>
+            | <a href="_sources/usage.txt">view source
+        </li>
+        </ul>
+    </div>
+
+    <div id="docs-navigation-banner">
+        <a href="index.html">Mako 0.7.3 Documentation</a>
+        » 
+                Usage
+             
+
+        <h2>
+            
+                Usage
+            
+        </h2>
+    </div>
+
+</div>
+
+<div id="docs-body-container">
+
+    <div id="docs-sidebar">
+    <h3><a href="index.html">Table of Contents</a></h3>
+    <ul>
+<li><a class="reference internal" href="#">Usage</a><ul>
+<li><a class="reference internal" href="#basic-usage">Basic Usage</a></li>
+<li><a class="reference internal" href="#using-file-based-templates">Using File-Based Templates</a></li>
+<li><a class="reference internal" href="#using-templatelookup">Using <tt class="docutils literal"><span class="pre">TemplateLookup</span></tt></a><ul>
+<li><a class="reference internal" href="#setting-the-collection-size">Setting the Collection Size</a></li>
+<li><a class="reference internal" href="#setting-filesystem-checks">Setting Filesystem Checks</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#using-unicode-and-encoding">Using Unicode and Encoding</a></li>
+<li><a class="reference internal" href="#handling-exceptions">Handling Exceptions</a></li>
+<li><a class="reference internal" href="#common-framework-integrations">Common Framework Integrations</a><ul>
+<li><a class="reference internal" href="#wsgi">WSGI</a></li>
+<li><a class="reference internal" href="#pygments">Pygments</a></li>
+<li><a class="reference internal" href="#babel">Babel</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#api-reference">API Reference</a></li>
+</ul>
+</li>
+</ul>
+
+
+    <h4>Previous Topic</h4>
+    <p>
+    <a href="index.html" title="previous chapter">Table of Contents</a>
+    </p>
+    <h4>Next Topic</h4>
+    <p>
+    <a href="syntax.html" title="next chapter">Syntax</a>
+    </p>
+
+    <h4>Quick Search</h4>
+    <p>
+    <form class="search" action="search.html" method="get">
+      <input type="text" name="q" size="18" /> <input type="submit" value="Search" />
+      <input type="hidden" name="check_keywords" value="yes" />
+      <input type="hidden" name="area" value="default" />
+    </form>
+    </p>
+
+    </div>
+
+    <div id="docs-body" class="withsidebar" >
+        
+<div class="section" id="usage">
+<span id="usage-toplevel"></span><h1>Usage<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="basic-usage">
+<h2>Basic Usage<a class="headerlink" href="#basic-usage" title="Permalink to this headline">¶</a></h2>
+<p>This section describes the Python API for Mako templates. If you
+are using Mako within a web framework such as Pylons, the work
+of integrating Mako’s API is already done for you, in which case
+you can skip to the next section, <a class="reference internal" href="syntax.html"><em>Syntax</em></a>.</p>
+<p>The most basic way to create a template and render it is through
+the <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> class:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+
+<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s">"hello world!"</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>Above, the text argument to <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> is <strong>compiled</strong> into a
+Python module representation. This module contains a function
+called <tt class="docutils literal"><span class="pre">render_body()</span></tt>, which produces the output of the
+template. When <tt class="docutils literal"><span class="pre">mytemplate.render()</span></tt> is called, Mako sets up a
+runtime environment for the template and calls the
+<tt class="docutils literal"><span class="pre">render_body()</span></tt> function, capturing the output into a buffer and
+returning its string contents.</p>
+<p>The code inside the <tt class="docutils literal"><span class="pre">render_body()</span></tt> function has access to a
+namespace of variables. You can specify these variables by
+sending them as additional keyword arguments to the <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a>
+method:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+
+<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s">"hello, ${name}!"</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">"jack"</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>The <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a> method calls upon Mako to create a
+<a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object, which stores all the variable names accessible
+to the template and also stores a buffer used to capture output.
+You can create this <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> yourself and have the template
+render with it, using the <a class="reference internal" href="#mako.template.Template.render_context" title="mako.template.Template.render_context"><tt class="xref py py-meth docutils literal"><span class="pre">render_context()</span></tt></a> method:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+<span class="kn">from</span> <span class="nn">mako.runtime</span> <span class="kn">import</span> <span class="n">Context</span>
+<span class="kn">from</span> <span class="nn">StringIO</span> <span class="kn">import</span> <span class="n">StringIO</span>
+
+<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s">"hello, ${name}!"</span><span class="p">)</span>
+<span class="n">buf</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>
+<span class="n">ctx</span> <span class="o">=</span> <span class="n">Context</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s">"jack"</span><span class="p">)</span>
+<span class="n">mytemplate</span><span class="o">.</span><span class="n">render_context</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">buf</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="using-file-based-templates">
+<h2>Using File-Based Templates<a class="headerlink" href="#using-file-based-templates" title="Permalink to this headline">¶</a></h2>
+<p>A <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> can also load its template source code from a file,
+using the <tt class="docutils literal"><span class="pre">filename</span></tt> keyword argument:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+
+<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s">'/docs/mytmpl.txt'</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>For improved performance, a <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> which is loaded from a
+file can also cache the source code to its generated module on
+the filesystem as a regular Python module file (i.e. a <tt class="docutils literal"><span class="pre">.py</span></tt>
+file). To do this, just add the <tt class="docutils literal"><span class="pre">module_directory</span></tt> argument to
+the template:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+
+<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s">'/docs/mytmpl.txt'</span><span class="p">,</span> <span class="n">module_directory</span><span class="o">=</span><span class="s">'/tmp/mako_modules'</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>When the above code is rendered, a file
+<tt class="docutils literal"><span class="pre">/tmp/mako_modules/docs/mytmpl.txt.py</span></tt> is created containing the
+source code for the module. The next time a <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> with the
+same arguments is created, this module file will be
+automatically re-used.</p>
+</div>
+<div class="section" id="using-templatelookup">
+<span id="usage-templatelookup"></span><h2>Using <tt class="docutils literal"><span class="pre">TemplateLookup</span></tt><a class="headerlink" href="#using-templatelookup" title="Permalink to this headline">¶</a></h2>
+<p>All of the examples thus far have dealt with the usage of a
+single <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object. If the code within those templates
+tries to locate another template resource, it will need some way
+to find them, using simple URI strings. For this need, the
+resolution of other templates from within a template is
+accomplished by the <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> class. This class is
+constructed given a list of directories in which to search for
+templates, as well as keyword arguments that will be passed to
+the <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> objects it creates:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+<span class="kn">from</span> <span class="nn">mako.lookup</span> <span class="kn">import</span> <span class="n">TemplateLookup</span>
+
+<span class="n">mylookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/docs'</span><span class="p">])</span>
+<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="s">"""<</span><span class="si">%i</span><span class="s">nclude file="header.txt"/> hello world!"""</span><span class="p">,</span> <span class="n">lookup</span><span class="o">=</span><span class="n">mylookup</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Above, we created a textual template which includes the file
+<tt class="docutils literal"><span class="pre">"header.txt"</span></tt>. In order for it to have somewhere to look for
+<tt class="docutils literal"><span class="pre">"header.txt"</span></tt>, we passed a <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> object to it, which
+will search in the directory <tt class="docutils literal"><span class="pre">/docs</span></tt> for the file <tt class="docutils literal"><span class="pre">"header.txt"</span></tt>.</p>
+<p>Usually, an application will store most or all of its templates
+as text files on the filesystem. So far, all of our examples
+have been a little bit contrived in order to illustrate the
+basic concepts. But a real application would get most or all of
+its templates directly from the <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>, using the
+aptly named <a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><tt class="xref py py-meth docutils literal"><span class="pre">get_template()</span></tt></a> method, which accepts the URI of the
+desired template:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+<span class="kn">from</span> <span class="nn">mako.lookup</span> <span class="kn">import</span> <span class="n">TemplateLookup</span>
+
+<span class="n">mylookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/docs'</span><span class="p">],</span> <span class="n">module_directory</span><span class="o">=</span><span class="s">'/tmp/mako_modules'</span><span class="p">)</span>
+
+<span class="k">def</span> <span class="nf">serve_template</span><span class="p">(</span><span class="n">templatename</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
+    <span class="n">mytemplate</span> <span class="o">=</span> <span class="n">mylookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">templatename</span><span class="p">)</span>
+    <span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>In the example above, we create a <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> which will
+look for templates in the <tt class="docutils literal"><span class="pre">/docs</span></tt> directory, and will store
+generated module files in the <tt class="docutils literal"><span class="pre">/tmp/mako_modules</span></tt> directory. The
+lookup locates templates by appending the given URI to each of
+its search directories; so if you gave it a URI of
+<tt class="docutils literal"><span class="pre">/etc/beans/info.txt</span></tt>, it would search for the file
+<tt class="docutils literal"><span class="pre">/docs/etc/beans/info.txt</span></tt>, else raise a <tt class="xref py py-class docutils literal"><span class="pre">TopLevelNotFound</span></tt>
+exception, which is a custom Mako exception.</p>
+<p>When the lookup locates templates, it will also assign a <tt class="docutils literal"><span class="pre">uri</span></tt>
+property to the <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> which is the URI passed to the
+<a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><tt class="xref py py-meth docutils literal"><span class="pre">get_template()</span></tt></a> call. <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> uses this URI to calculate the
+name of its module file. So in the above example, a
+<tt class="docutils literal"><span class="pre">templatename</span></tt> argument of <tt class="docutils literal"><span class="pre">/etc/beans/info.txt</span></tt> will create a
+module file <tt class="docutils literal"><span class="pre">/tmp/mako_modules/etc/beans/info.txt.py</span></tt>.</p>
+<div class="section" id="setting-the-collection-size">
+<h3>Setting the Collection Size<a class="headerlink" href="#setting-the-collection-size" title="Permalink to this headline">¶</a></h3>
+<p>The <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> also serves the important need of caching a
+fixed set of templates in memory at a given time, so that
+successive URI lookups do not result in full template
+compilations and/or module reloads on each request. By default,
+the <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> size is unbounded. You can specify a fixed
+size using the <tt class="docutils literal"><span class="pre">collection_size</span></tt> argument:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">mylookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/docs'</span><span class="p">],</span>
+                <span class="n">module_directory</span><span class="o">=</span><span class="s">'/tmp/mako_modules'</span><span class="p">,</span> <span class="n">collection_size</span><span class="o">=</span><span class="mi">500</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>The above lookup will continue to load templates into memory
+until it reaches a count of around 500. At that point, it will
+clean out a certain percentage of templates using a least
+recently used scheme.</p>
+</div>
+<div class="section" id="setting-filesystem-checks">
+<h3>Setting Filesystem Checks<a class="headerlink" href="#setting-filesystem-checks" title="Permalink to this headline">¶</a></h3>
+<p>Another important flag on <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> is
+<tt class="docutils literal"><span class="pre">filesystem_checks</span></tt>. This defaults to <tt class="docutils literal"><span class="pre">True</span></tt>, and says that each
+time a template is returned by the <a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><tt class="xref py py-meth docutils literal"><span class="pre">get_template()</span></tt></a> method, the
+revision time of the original template file is checked against
+the last time the template was loaded, and if the file is newer
+will reload its contents and recompile the template. On a
+production system, setting <tt class="docutils literal"><span class="pre">filesystem_checks</span></tt> to <tt class="docutils literal"><span class="pre">False</span></tt> can
+afford a small to moderate performance increase (depending on
+the type of filesystem used).</p>
+</div>
+</div>
+<div class="section" id="using-unicode-and-encoding">
+<span id="usage-unicode"></span><h2>Using Unicode and Encoding<a class="headerlink" href="#using-unicode-and-encoding" title="Permalink to this headline">¶</a></h2>
+<p>Both <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> and <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> accept <tt class="docutils literal"><span class="pre">output_encoding</span></tt>
+and <tt class="docutils literal"><span class="pre">encoding_errors</span></tt> parameters which can be used to encode the
+output in any Python supported codec:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+<span class="kn">from</span> <span class="nn">mako.lookup</span> <span class="kn">import</span> <span class="n">TemplateLookup</span>
+
+<span class="n">mylookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">(</span><span class="n">directories</span><span class="o">=</span><span class="p">[</span><span class="s">'/docs'</span><span class="p">],</span> <span class="n">output_encoding</span><span class="o">=</span><span class="s">'utf-8'</span><span class="p">,</span> <span class="n">encoding_errors</span><span class="o">=</span><span class="s">'replace'</span><span class="p">)</span>
+
+<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">mylookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">"foo.txt"</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>When using Python 3, the <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a> method will return a <tt class="docutils literal"><span class="pre">bytes</span></tt>
+object, <strong>if</strong> <tt class="docutils literal"><span class="pre">output_encoding</span></tt> is set. Otherwise it returns a
+<tt class="docutils literal"><span class="pre">string</span></tt>.</p>
+<p>Additionally, the <a class="reference internal" href="#mako.template.Template.render_unicode" title="mako.template.Template.render_unicode"><tt class="xref py py-meth docutils literal"><span class="pre">render_unicode()</span></tt></a> method exists which will
+return the template output as a Python <tt class="docutils literal"><span class="pre">unicode</span></tt> object, or in
+Python 3 a <tt class="docutils literal"><span class="pre">string</span></tt>:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>The above method disregards the output encoding keyword
+argument; you can encode yourself by saying:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="k">print</span> <span class="n">mytemplate</span><span class="o">.</span><span class="n">render_unicode</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">'utf-8'</span><span class="p">,</span> <span class="s">'replace'</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Note that Mako’s ability to return data in any encoding and/or
+<tt class="docutils literal"><span class="pre">unicode</span></tt> implies that the underlying output stream of the
+template is a Python unicode object. This behavior is described
+fully in <a class="reference internal" href="unicode.html"><em>The Unicode Chapter</em></a>.</p>
+</div>
+<div class="section" id="handling-exceptions">
+<span id="id1"></span><h2>Handling Exceptions<a class="headerlink" href="#handling-exceptions" title="Permalink to this headline">¶</a></h2>
+<p>Template exceptions can occur in two distinct places. One is
+when you <strong>lookup, parse and compile</strong> the template, the other
+is when you <strong>run</strong> the template. Within the running of a
+template, exceptions are thrown normally from whatever Python
+code originated the issue. Mako has its own set of exception
+classes which mostly apply to the lookup and lexer/compiler
+stages of template construction. Mako provides some library
+routines that can be used to help provide Mako-specific
+information about any exception’s stack trace, as well as
+formatting the exception within textual or HTML format. In all
+cases, the main value of these handlers is that of converting
+Python filenames, line numbers, and code samples into Mako
+template filenames, line numbers, and code samples. All lines
+within a stack trace which correspond to a Mako template module
+will be converted to be against the originating template file.</p>
+<p>To format exception traces, the <a class="reference internal" href="#mako.exceptions.text_error_template" title="mako.exceptions.text_error_template"><tt class="xref py py-func docutils literal"><span class="pre">text_error_template()</span></tt></a> and
+<a class="reference internal" href="#mako.exceptions.html_error_template" title="mako.exceptions.html_error_template"><tt class="xref py py-func docutils literal"><span class="pre">html_error_template()</span></tt></a> functions are provided. They make usage of
+<tt class="docutils literal"><span class="pre">sys.exc_info()</span></tt> to get at the most recently thrown exception.
+Usage of these handlers usually looks like:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako</span> <span class="kn">import</span> <span class="n">exceptions</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">template</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span>
+    <span class="k">print</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+<span class="k">except</span><span class="p">:</span>
+    <span class="k">print</span> <span class="n">exceptions</span><span class="o">.</span><span class="n">text_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>Or for the HTML render function:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako</span> <span class="kn">import</span> <span class="n">exceptions</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">template</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span>
+    <span class="k">print</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+<span class="k">except</span><span class="p">:</span>
+    <span class="k">print</span> <span class="n">exceptions</span><span class="o">.</span><span class="n">html_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>The <a class="reference internal" href="#mako.exceptions.html_error_template" title="mako.exceptions.html_error_template"><tt class="xref py py-func docutils literal"><span class="pre">html_error_template()</span></tt></a> template accepts two options:
+specifying <tt class="docutils literal"><span class="pre">full=False</span></tt> causes only a section of an HTML
+document to be rendered. Specifying <tt class="docutils literal"><span class="pre">css=False</span></tt> will disable the
+default stylesheet from being rendered.</p>
+<p>E.g.:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="k">print</span> <span class="n">exceptions</span><span class="o">.</span><span class="n">html_error_template</span><span class="p">()</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">full</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>The HTML render function is also available built-in to
+<a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> using the <tt class="docutils literal"><span class="pre">format_exceptions</span></tt> flag. In this case, any
+exceptions raised within the <strong>render</strong> stage of the template
+will result in the output being substituted with the output of
+<a class="reference internal" href="#mako.exceptions.html_error_template" title="mako.exceptions.html_error_template"><tt class="xref py py-func docutils literal"><span class="pre">html_error_template()</span></tt></a>:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">template</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="n">filename</span><span class="o">=</span><span class="s">"/foo/bar"</span><span class="p">,</span> <span class="n">format_exceptions</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
+<span class="k">print</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>Note that the compile stage of the above template occurs when
+you construct the <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> itself, and no output stream is
+defined. Therefore exceptions which occur within the
+lookup/parse/compile stage will not be handled and will
+propagate normally. While the pre-render traceback usually will
+not include any Mako-specific lines anyway, it will mean that
+exceptions which occur previous to rendering and those which
+occur within rendering will be handled differently... so the
+<tt class="docutils literal"><span class="pre">try</span></tt>/<tt class="docutils literal"><span class="pre">except</span></tt> patterns described previously are probably of more
+general use.</p>
+<p>The underlying object used by the error template functions is
+the <a class="reference internal" href="#mako.exceptions.RichTraceback" title="mako.exceptions.RichTraceback"><tt class="xref py py-class docutils literal"><span class="pre">RichTraceback</span></tt></a> object. This object can also be used
+directly to provide custom error views. Here’s an example usage
+which describes its general API:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">mako.exceptions</span> <span class="kn">import</span> <span class="n">RichTraceback</span>
+
+<span class="k">try</span><span class="p">:</span>
+    <span class="n">template</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="n">uri</span><span class="p">)</span>
+    <span class="k">print</span> <span class="n">template</span><span class="o">.</span><span class="n">render</span><span class="p">()</span>
+<span class="k">except</span><span class="p">:</span>
+    <span class="n">traceback</span> <span class="o">=</span> <span class="n">RichTraceback</span><span class="p">()</span>
+    <span class="k">for</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">function</span><span class="p">,</span> <span class="n">line</span><span class="p">)</span> <span class="ow">in</span> <span class="n">traceback</span><span class="o">.</span><span class="n">traceback</span><span class="p">:</span>
+        <span class="k">print</span> <span class="s">"File </span><span class="si">%s</span><span class="s">, line </span><span class="si">%s</span><span class="s">, in </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">function</span><span class="p">)</span>
+        <span class="k">print</span> <span class="n">line</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span>
+    <span class="k">print</span> <span class="s">"</span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">traceback</span><span class="o">.</span><span class="n">error</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">),</span> <span class="n">traceback</span><span class="o">.</span><span class="n">error</span><span class="p">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="common-framework-integrations">
+<h2>Common Framework Integrations<a class="headerlink" href="#common-framework-integrations" title="Permalink to this headline">¶</a></h2>
+<p>The Mako distribution includes a little bit of helper code for
+the purpose of using Mako in some popular web framework
+scenarios. This is a brief description of what’s included.</p>
+<div class="section" id="wsgi">
+<h3>WSGI<a class="headerlink" href="#wsgi" title="Permalink to this headline">¶</a></h3>
+<p>A sample WSGI application is included in the distribution in the
+file <tt class="docutils literal"><span class="pre">examples/wsgi/run_wsgi.py</span></tt>. This runner is set up to pull
+files from a <cite>templates</cite> as well as an <cite>htdocs</cite> directory and
+includes a rudimental two-file layout. The WSGI runner acts as a
+fully functional standalone web server, using <tt class="docutils literal"><span class="pre">wsgiutils</span></tt> to run
+itself, and propagates GET and POST arguments from the request
+into the <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a>, can serve images, CSS files and other kinds
+of files, and also displays errors using Mako’s included
+exception-handling utilities.</p>
+</div>
+<div class="section" id="pygments">
+<h3>Pygments<a class="headerlink" href="#pygments" title="Permalink to this headline">¶</a></h3>
+<p>A <a class="reference external" href="http://pygments.pocoo.org">Pygments</a>-compatible syntax
+highlighting module is included under <tt class="xref py py-mod docutils literal"><span class="pre">mako.ext.pygmentplugin</span></tt>.
+This module is used in the generation of Mako documentation and
+also contains various <cite>setuptools</cite> entry points under the heading
+<tt class="docutils literal"><span class="pre">pygments.lexers</span></tt>, including <tt class="docutils literal"><span class="pre">mako</span></tt>, <tt class="docutils literal"><span class="pre">html+mako</span></tt>, <tt class="docutils literal"><span class="pre">xml+mako</span></tt>
+(see the <tt class="docutils literal"><span class="pre">setup.py</span></tt> file for all the entry points).</p>
+</div>
+<div class="section" id="babel">
+<h3>Babel<a class="headerlink" href="#babel" title="Permalink to this headline">¶</a></h3>
+<p>Mako provides support for extracting <cite>gettext</cite> messages from
+templates via a <a class="reference external" href="http://babel.edgewall.org/">Babel</a> extractor
+entry point under <tt class="docutils literal"><span class="pre">mako.ext.babelplugin</span></tt>.</p>
+<p><cite>Gettext</cite> messages are extracted from all Python code sections,
+including those of control lines and expressions embedded
+in tags.</p>
+<p><a class="reference external" href="http://babel.edgewall.org/wiki/Documentation/messages.html#comments-tags-and-translator-comments-explanation">Translator
+comments</a>
+may also be extracted from Mako templates when a comment tag is
+specified to <a class="reference external" href="http://babel.edgewall.org/">Babel</a> (such as with
+the <tt class="docutils literal"><span class="pre">-c</span></tt> option).</p>
+<p>For example, a project <tt class="docutils literal"><span class="pre">"myproj"</span></tt> contains the following Mako
+template at <tt class="docutils literal"><span class="pre">myproj/myproj/templates/name.html</span></tt>:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><div id="name"></span>
+<span class="x">  Name:</span>
+<span class="x">  ## TRANSLATORS: This is a proper name. See the gettext</span>
+<span class="x">  ## manual, section Names.</span>
+<span class="x">  </span><span class="cp">${</span><span class="n">_</span><span class="p">(</span><span class="s">'Francois Pinard'</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+<span class="x"></div></span>
+</pre></div>
+</div>
+<p>To extract gettext messages from this template the project needs
+a Mako section in its <a class="reference external" href="http://babel.edgewall.org/wiki/Documentation/messages.html#extraction-method-mapping-and-configuration">Babel Extraction Method Mapping
+file</a>
+(typically located at <tt class="docutils literal"><span class="pre">myproj/babel.cfg</span></tt>):</p>
+<div class="highlight-cfg"><div class="highlight"><pre><span class="c"># Extraction from Python source files</span>
+
+<span class="k">[python: myproj/**.py]</span>
+
+<span class="c"># Extraction from Mako templates</span>
+
+<span class="k">[mako: myproj/templates/**.html]</span>
+<span class="na">input_encoding</span> <span class="o">=</span> <span class="s">utf-8</span>
+</pre></div>
+</div>
+<p>The Mako extractor supports an optional <tt class="docutils literal"><span class="pre">input_encoding</span></tt>
+parameter specifying the encoding of the templates (identical to
+<a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>/<a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>‘s <tt class="docutils literal"><span class="pre">input_encoding</span></tt> parameter).</p>
+<p>Invoking <a class="reference external" href="http://babel.edgewall.org/">Babel</a>‘s extractor at the
+command line in the project’s root directory:</p>
+<div class="highlight-sh"><div class="highlight"><pre>myproj<span class="nv">$ </span>pybabel extract -F babel.cfg -c <span class="s2">"TRANSLATORS:"</span> .
+</pre></div>
+</div>
+<p>will output a <cite>gettext</cite> catalog to <cite>stdout</cite> including the following:</p>
+<div class="highlight-pot"><div class="highlight"><pre><span class="c1">#. TRANSLATORS: This is a proper name. See the gettext</span>
+<span class="c1">#. manual, section Names.</span>
+<span class="kd">#: myproj/templates/name.html:5</span>
+<span class="nv">msgid</span> <span class="s">"Francois Pinard"</span>
+<span class="nv">msgstr</span> <span class="s">""</span>
+</pre></div>
+</div>
+<p>This is only a basic example:
+<a class="reference external" href="http://babel.edgewall.org/">Babel</a> can be invoked from <tt class="docutils literal"><span class="pre">setup.py</span></tt>
+and its command line options specified in the accompanying
+<tt class="docutils literal"><span class="pre">setup.cfg</span></tt> via <a class="reference external" href="http://babel.edgewall.org/wiki/Documentation/setup.html">Babel Distutils/Setuptools
+Integration</a>.</p>
+<p>Comments must immediately precede a <cite>gettext</cite> message to be
+extracted. In the following case the <tt class="docutils literal"><span class="pre">TRANSLATORS:</span></tt> comment would
+not have been extracted:</p>
+<div class="highlight-mako"><div class="highlight"><pre><span class="x"><div id="name"></span>
+<span class="x">  ## TRANSLATORS: This is a proper name. See the gettext</span>
+<span class="x">  ## manual, section Names.</span>
+<span class="x">  Name: </span><span class="cp">${</span><span class="n">_</span><span class="p">(</span><span class="s">'Francois Pinard'</span><span class="p">)</span><span class="cp">}</span><span class="x"></span>
+<span class="x"></div></span>
+</pre></div>
+</div>
+<p>See the <a class="reference external" href="http://babel.edgewall.org/wiki/Documentation/index.html">Babel User
+Guide</a>
+for more information.</p>
+</div>
+</div>
+<div class="section" id="api-reference">
+<h2>API Reference<a class="headerlink" href="#api-reference" title="Permalink to this headline">¶</a></h2>
+<dl class="class">
+<dt id="mako.template.Template">
+<em class="property">class </em><tt class="descclassname">mako.template.</tt><tt class="descname">Template</tt><big>(</big><em>text=None</em>, <em>filename=None</em>, <em>uri=None</em>, <em>format_exceptions=False</em>, <em>error_handler=None</em>, <em>lookup=None</em>, <em>output_encoding=None</em>, <em>encoding_errors='strict'</em>, <em>module_directory=None</em>, <em>cache_args=None</em>, <em>cache_impl='beaker'</em>, <em>cache_enabled=True</em>, <em>cache_type=None</em>, <em>cache_dir=None</em>, <em>cache_url=None</em>, <em>module_filename=None</em>, <em>input_encoding=None</em>, <em>disable_unicode=False</em>, <em>module_writer=None</em>, <em>bytestring_passthrough=False</em>, <em>default_filters=None</em>, <em>buffer_filters=()</em>, <em>strict_undefined=False</em>, <em>imports=None</em>, <em>enable_loop=True</em>, <em>preprocessor=None</em><big>)</big><a class="headerlink" href="#mako.template.Template" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
+<p>Represents a compiled template.</p>
+<p><a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> includes a reference to the original
+template source (via the <a class="reference internal" href="#RichTraceback.source" title="RichTraceback.source"><tt class="xref py py-attr docutils literal"><span class="pre">source</span></tt></a> attribute)
+as well as the source code of the
+generated Python module (i.e. the <a class="reference internal" href="#mako.template.Template.code" title="mako.template.Template.code"><tt class="xref py py-attr docutils literal"><span class="pre">code</span></tt></a> attribute),
+as well as a reference to an actual Python module.</p>
+<p><a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> is constructed using either a literal string
+representing the template text, or a filename representing a filesystem
+path to a source file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>text</strong> – textual template source.  This argument is mutually
+exclusive versus the <tt class="docutils literal"><span class="pre">filename</span></tt> parameter.</li>
+<li><strong>filename</strong> – filename of the source template.  This argument is
+mutually exclusive versus the <tt class="docutils literal"><span class="pre">text</span></tt> parameter.</li>
+<li><strong>buffer_filters</strong> – string list of filters to be applied
+to the output of <tt class="docutils literal"><span class="pre">%def</span></tt>s which are buffered, cached, or otherwise
+filtered, after all filters
+defined with the <tt class="docutils literal"><span class="pre">%def</span></tt> itself have been applied. Allows the
+creation of default expression filters that let the output
+of return-valued <tt class="docutils literal"><span class="pre">%def</span></tt>s “opt out” of that filtering via
+passing special attributes or objects.</li>
+<li><strong>bytestring_passthrough</strong> – <p>When <tt class="docutils literal"><span class="pre">True</span></tt>, and <tt class="docutils literal"><span class="pre">output_encoding</span></tt> is
+set to <tt class="docutils literal"><span class="pre">None</span></tt>, and <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">Template.render()</span></tt></a> is used to render,
+the <cite>StringIO</cite> or <cite>cStringIO</cite> buffer will be used instead of the
+default “fast” buffer.   This allows raw bytestrings in the
+output stream, such as in expressions, to pass straight
+through to the buffer.  This flag is forced
+to <tt class="docutils literal"><span class="pre">True</span></tt> if <tt class="docutils literal"><span class="pre">disable_unicode</span></tt> is also configured.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.4: </span>Added to provide the same behavior as that of the previous series.</p>
+</li>
+<li><strong>cache_args</strong> – Dictionary of cache configuration arguments that
+will be passed to the <a class="reference internal" href="caching.html#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a>.   See <a class="reference internal" href="caching.html"><em>Caching</em></a>.</li>
+<li><strong>cache_dir</strong> – <p class="deprecated">
+<span class="versionmodified">Deprecated since version 0.6: </span>Use the <tt class="docutils literal"><span class="pre">'dir'</span></tt> argument in the <tt class="docutils literal"><span class="pre">cache_args</span></tt> dictionary.
+See <a class="reference internal" href="caching.html"><em>Caching</em></a>.</p>
+</li>
+<li><strong>cache_enabled</strong> – Boolean flag which enables caching of this
+template.  See <a class="reference internal" href="caching.html"><em>Caching</em></a>.</li>
+<li><strong>cache_impl</strong> – String name of a <a class="reference internal" href="caching.html#mako.cache.CacheImpl" title="mako.cache.CacheImpl"><tt class="xref py py-class docutils literal"><span class="pre">CacheImpl</span></tt></a> caching
+implementation to use.   Defaults to <tt class="docutils literal"><span class="pre">'beaker'</span></tt>.</li>
+<li><strong>cache_type</strong> – <p class="deprecated">
+<span class="versionmodified">Deprecated since version 0.6: </span>Use the <tt class="docutils literal"><span class="pre">'type'</span></tt> argument in the <tt class="docutils literal"><span class="pre">cache_args</span></tt> dictionary.
+See <a class="reference internal" href="caching.html"><em>Caching</em></a>.</p>
+</li>
+<li><strong>cache_url</strong> – <p class="deprecated">
+<span class="versionmodified">Deprecated since version 0.6: </span>Use the <tt class="docutils literal"><span class="pre">'url'</span></tt> argument in the <tt class="docutils literal"><span class="pre">cache_args</span></tt> dictionary.
+See <a class="reference internal" href="caching.html"><em>Caching</em></a>.</p>
+</li>
+<li><strong>default_filters</strong> – List of string filter names that will
+be applied to all expressions.  See <a class="reference internal" href="filtering.html#filtering-default-filters"><em>The default_filters Argument</em></a>.</li>
+<li><strong>disable_unicode</strong> – Disables all awareness of Python Unicode
+objects.  See <a class="reference internal" href="unicode.html#unicode-disabled"><em>Saying to Heck with It: Disabling the Usage of Unicode Entirely</em></a>.</li>
+<li><strong>enable_loop</strong> – When <tt class="docutils literal"><span class="pre">True</span></tt>, enable the <tt class="docutils literal"><span class="pre">loop</span></tt> context variable.
+This can be set to <tt class="docutils literal"><span class="pre">False</span></tt> to support templates that may
+be making usage of the name “<tt class="docutils literal"><span class="pre">loop</span></tt>”.   Individual templates can
+re-enable the “loop” context by placing the directive
+<tt class="docutils literal"><span class="pre">enable_loop="True"</span></tt> inside the <tt class="docutils literal"><span class="pre"><%page></span></tt> tag – see
+<a class="reference internal" href="runtime.html#migrating-loop"><em>Migrating Legacy Templates that Use the Word “loop”</em></a>.</li>
+<li><strong>encoding_errors</strong> – Error parameter passed to <tt class="docutils literal"><span class="pre">encode()</span></tt> when
+string encoding is performed. See <a class="reference internal" href="#usage-unicode"><em>Using Unicode and Encoding</em></a>.</li>
+<li><strong>error_handler</strong> – Python callable which is called whenever
+compile or runtime exceptions occur. The callable is passed
+the current context as well as the exception. If the
+callable returns <tt class="docutils literal"><span class="pre">True</span></tt>, the exception is considered to
+be handled, else it is re-raised after the function
+completes. Is used to provide custom error-rendering
+functions.</li>
+<li><strong>format_exceptions</strong> – if <tt class="docutils literal"><span class="pre">True</span></tt>, exceptions which occur during
+the render phase of this template will be caught and
+formatted into an HTML error page, which then becomes the
+rendered result of the <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a> call. Otherwise,
+runtime exceptions are propagated outwards.</li>
+<li><strong>imports</strong> – String list of Python statements, typically individual
+“import” lines, which will be placed into the module level
+preamble of all generated Python modules. See the example
+in <a class="reference internal" href="filtering.html#filtering-default-filters"><em>The default_filters Argument</em></a>.</li>
+<li><strong>input_encoding</strong> – Encoding of the template’s source code.  Can
+be used in lieu of the coding comment. See
+<a class="reference internal" href="#usage-unicode"><em>Using Unicode and Encoding</em></a> as well as <a class="reference internal" href="unicode.html"><em>The Unicode Chapter</em></a> for
+details on source encoding.</li>
+<li><strong>lookup</strong> – a <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> instance that will be used
+for all file lookups via the <tt class="docutils literal"><span class="pre"><%namespace></span></tt>,
+<tt class="docutils literal"><span class="pre"><%include></span></tt>, and <tt class="docutils literal"><span class="pre"><%inherit></span></tt> tags. See
+<a class="reference internal" href="#usage-templatelookup"><em>Using TemplateLookup</em></a>.</li>
+<li><strong>module_directory</strong> – Filesystem location where generated
+Python module files will be placed.</li>
+<li><strong>module_filename</strong> – Overrides the filename of the generated
+Python module file. For advanced usage only.</li>
+<li><strong>module_writer</strong> – <p>A callable which overrides how the Python
+module is written entirely.  The callable is passed the
+encoded source content of the module and the destination
+path to be written to.   The default behavior of module writing
+uses a tempfile in conjunction with a file move in order
+to make the operation atomic.   So a user-defined module
+writing function that mimics the default behavior would be:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">tempfile</span>
+<span class="kn">import</span> <span class="nn">os</span>
+<span class="kn">import</span> <span class="nn">shutil</span>
+
+<span class="k">def</span> <span class="nf">module_writer</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">outputpath</span><span class="p">):</span>
+    <span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="o">=</span> \
+        <span class="n">tempfile</span><span class="o">.</span><span class="n">mkstemp</span><span class="p">(</span>
+            <span class="nb">dir</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">outputpath</span><span class="p">)</span>
+        <span class="p">)</span>
+
+    <span class="n">os</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="n">source</span><span class="p">)</span>
+    <span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">dest</span><span class="p">)</span>
+    <span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">outputpath</span><span class="p">)</span>
+
+<span class="kn">from</span> <span class="nn">mako.template</span> <span class="kn">import</span> <span class="n">Template</span>
+<span class="n">mytemplate</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span>
+                <span class="nb">file</span><span class="o">=</span><span class="s">"index.html"</span><span class="p">,</span>
+                <span class="n">module_directory</span><span class="o">=</span><span class="s">"/path/to/modules"</span><span class="p">,</span>
+                <span class="n">module_writer</span><span class="o">=</span><span class="n">module_writer</span>
+            <span class="p">)</span>
+</pre></div>
+</div>
+<p>The function is provided for unusual configurations where
+certain platform-specific permissions or other special
+steps are needed.</p>
+</li>
+<li><strong>output_encoding</strong> – The encoding to use when <a class="reference internal" href="#mako.template.Template.render" title="mako.template.Template.render"><tt class="xref py py-meth docutils literal"><span class="pre">render()</span></tt></a>
+is called.
+See <a class="reference internal" href="#usage-unicode"><em>Using Unicode and Encoding</em></a> as well as <a class="reference internal" href="unicode.html"><em>The Unicode Chapter</em></a>.</li>
+<li><strong>preprocessor</strong> – Python callable which will be passed
+the full template source before it is parsed. The return
+result of the callable will be used as the template source
+code.</li>
+<li><strong>strict_undefined</strong> – <p>Replaces the automatic usage of
+<tt class="docutils literal"><span class="pre">UNDEFINED</span></tt> for any undeclared variables not located in
+the <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> with an immediate raise of
+<tt class="docutils literal"><span class="pre">NameError</span></tt>. The advantage is immediate reporting of
+missing variables which include the name.</p>
+<p class="versionadded">
+<span class="versionmodified">New in version 0.3.6.</span></p>
+</li>
+<li><strong>uri</strong> – string URI or other identifier for this template.
+If not provided, the <tt class="docutils literal"><span class="pre">uri</span></tt> is generated from the filesystem
+path, or from the in-memory identity of a non-file-based
+template. The primary usage of the <tt class="docutils literal"><span class="pre">uri</span></tt> is to provide a key
+within <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>, as well as to generate the
+file path of the generated Python module file, if
+<tt class="docutils literal"><span class="pre">module_directory</span></tt> is specified.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<dl class="attribute">
+<dt id="mako.template.Template.code">
+<tt class="descname">code</tt><a class="headerlink" href="#mako.template.Template.code" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the module source code for this <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.template.Template.get_def">
+<tt class="descname">get_def</tt><big>(</big><em>name</em><big>)</big><a class="headerlink" href="#mako.template.Template.get_def" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return a def of this template as a <a class="reference internal" href="#mako.template.DefTemplate" title="mako.template.DefTemplate"><tt class="xref py py-class docutils literal"><span class="pre">DefTemplate</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.template.Template.render">
+<tt class="descname">render</tt><big>(</big><em>*args</em>, <em>**data</em><big>)</big><a class="headerlink" href="#mako.template.Template.render" title="Permalink to this definition">¶</a></dt>
+<dd><p>Render the output of this template as a string.</p>
+<p>If the template specifies an output encoding, the string
+will be encoded accordingly, else the output is raw (raw
+output uses <cite>cStringIO</cite> and can’t handle multibyte
+characters). A <a class="reference internal" href="runtime.html#mako.runtime.Context" title="mako.runtime.Context"><tt class="xref py py-class docutils literal"><span class="pre">Context</span></tt></a> object is created corresponding
+to the given data. Arguments that are explicitly declared
+by this template’s internal rendering method are also
+pulled from the given <tt class="docutils literal"><span class="pre">*args</span></tt>, <tt class="docutils literal"><span class="pre">**data</span></tt> members.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.template.Template.render_context">
+<tt class="descname">render_context</tt><big>(</big><em>context</em>, <em>*args</em>, <em>**kwargs</em><big>)</big><a class="headerlink" href="#mako.template.Template.render_context" title="Permalink to this definition">¶</a></dt>
+<dd><p>Render this <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> with the given context.</p>
+<p>The data is written to the context’s buffer.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.template.Template.render_unicode">
+<tt class="descname">render_unicode</tt><big>(</big><em>*args</em>, <em>**data</em><big>)</big><a class="headerlink" href="#mako.template.Template.render_unicode" title="Permalink to this definition">¶</a></dt>
+<dd><p>Render the output of this template as a unicode object.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="mako.template.Template.source">
+<tt class="descname">source</tt><a class="headerlink" href="#mako.template.Template.source" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the template source code for this <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="mako.template.DefTemplate">
+<em class="property">class </em><tt class="descclassname">mako.template.</tt><tt class="descname">DefTemplate</tt><big>(</big><em>parent</em>, <em>callable_</em><big>)</big><a class="headerlink" href="#mako.template.DefTemplate" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">mako.template.Template</span></tt></a></p>
+<p>A <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> which represents a callable def in a parent
+template.</p>
+</dd></dl>
+
+<dl class="class">
+<dt id="mako.lookup.TemplateCollection">
+<em class="property">class </em><tt class="descclassname">mako.lookup.</tt><tt class="descname">TemplateCollection</tt><a class="headerlink" href="#mako.lookup.TemplateCollection" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
+<p>Represent a collection of <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> objects,
+identifiable via URI.</p>
+<p>A <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><tt class="xref py py-class docutils literal"><span class="pre">TemplateCollection</span></tt></a> is linked to the usage of
+all template tags that address other templates, such
+as <tt class="docutils literal"><span class="pre"><%include></span></tt>, <tt class="docutils literal"><span class="pre"><%namespace></span></tt>, and <tt class="docutils literal"><span class="pre"><%inherit></span></tt>.
+The <tt class="docutils literal"><span class="pre">file</span></tt> attribute of each of those tags refers
+to a string URI that is passed to that <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>
+object’s <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><tt class="xref py py-class docutils literal"><span class="pre">TemplateCollection</span></tt></a> for resolution.</p>
+<p><a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><tt class="xref py py-class docutils literal"><span class="pre">TemplateCollection</span></tt></a> is an abstract class,
+with the usual default implementation being <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>.</p>
+<dl class="method">
+<dt id="mako.lookup.TemplateCollection.adjust_uri">
+<tt class="descname">adjust_uri</tt><big>(</big><em>uri</em>, <em>filename</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateCollection.adjust_uri" title="Permalink to this definition">¶</a></dt>
+<dd><p>Adjust the given <tt class="docutils literal"><span class="pre">uri</span></tt> based on the calling <tt class="docutils literal"><span class="pre">filename</span></tt>.</p>
+<p>When this method is called from the runtime, the
+<tt class="docutils literal"><span class="pre">filename</span></tt> parameter is taken directly to the <tt class="docutils literal"><span class="pre">filename</span></tt>
+attribute of the calling template. Therefore a custom
+<a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><tt class="xref py py-class docutils literal"><span class="pre">TemplateCollection</span></tt></a> subclass can place any string
+identifier desired in the <tt class="docutils literal"><span class="pre">filename</span></tt> parameter of the
+<a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> objects it constructs and have them come back
+here.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.lookup.TemplateCollection.filename_to_uri">
+<tt class="descname">filename_to_uri</tt><big>(</big><em>uri</em>, <em>filename</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateCollection.filename_to_uri" title="Permalink to this definition">¶</a></dt>
+<dd><p>Convert the given <tt class="docutils literal"><span class="pre">filename</span></tt> to a URI relative to
+this <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><tt class="xref py py-class docutils literal"><span class="pre">TemplateCollection</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.lookup.TemplateCollection.get_template">
+<tt class="descname">get_template</tt><big>(</big><em>uri</em>, <em>relativeto=None</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateCollection.get_template" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return a <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object corresponding to the given
+<tt class="docutils literal"><span class="pre">uri</span></tt>.</p>
+<p>The default implementation raises
+<tt class="xref py py-class docutils literal"><span class="pre">NotImplementedError</span></tt>. Implementations should
+raise <tt class="xref py py-class docutils literal"><span class="pre">TemplateLookupException</span></tt> if the given <tt class="docutils literal"><span class="pre">uri</span></tt>
+cannot be resolved.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>uri</strong> – String URI of the template to be resolved.</li>
+<li><strong>relativeto</strong> – if present, the given <tt class="docutils literal"><span class="pre">uri</span></tt> is assumed to
+be relative to this URI.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.lookup.TemplateCollection.has_template">
+<tt class="descname">has_template</tt><big>(</big><em>uri</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateCollection.has_template" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return <tt class="docutils literal"><span class="pre">True</span></tt> if this <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> is
+capable of returning a <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object for the
+given <tt class="docutils literal"><span class="pre">uri</span></tt>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>uri</strong> – String URI of the template to be resolved.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="mako.lookup.TemplateLookup">
+<em class="property">class </em><tt class="descclassname">mako.lookup.</tt><tt class="descname">TemplateLookup</tt><big>(</big><em>directories=None</em>, <em>module_directory=None</em>, <em>filesystem_checks=True</em>, <em>collection_size=-1</em>, <em>format_exceptions=False</em>, <em>error_handler=None</em>, <em>disable_unicode=False</em>, <em>bytestring_passthrough=False</em>, <em>output_encoding=None</em>, <em>encoding_errors='strict'</em>, <em>cache_args=None</em>, <em>cache_impl='beaker'</em>, <em>cache_enabled=True</em>, <em>cache_type=None</em>, <em>cache_dir=None</em>, <em>cache_url=None</em>, <em>modulename_callable=None</em>, <em>module_writer=None</em>, <em>default_filters=None</em>, <em>buffer_filters=()</em>, <em>strict_undefined=False</em>, <em>imports=None</em>, <em>enable_loop=True</em>, <em>input_encoding=None</em>, <em>preprocessor=None</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateLookup" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><tt class="xref py py-class docutils literal"><span class="pre">mako.lookup.TemplateCollection</span></tt></a></p>
+<p>Represent a collection of templates that locates template source files
+from the local filesystem.</p>
+<p>The primary argument is the <tt class="docutils literal"><span class="pre">directories</span></tt> argument, the list of
+directories to search:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">([</span><span class="s">"/path/to/templates"</span><span class="p">])</span>
+<span class="n">some_template</span> <span class="o">=</span> <span class="n">lookup</span><span class="o">.</span><span class="n">get_template</span><span class="p">(</span><span class="s">"/index.html"</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>The <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> can also be given <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> objects
+programatically using <a class="reference internal" href="#mako.lookup.TemplateLookup.put_string" title="mako.lookup.TemplateLookup.put_string"><tt class="xref py py-meth docutils literal"><span class="pre">put_string()</span></tt></a> or <a class="reference internal" href="#mako.lookup.TemplateLookup.put_template" title="mako.lookup.TemplateLookup.put_template"><tt class="xref py py-meth docutils literal"><span class="pre">put_template()</span></tt></a>:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">lookup</span> <span class="o">=</span> <span class="n">TemplateLookup</span><span class="p">()</span>
+<span class="n">lookup</span><span class="o">.</span><span class="n">put_string</span><span class="p">(</span><span class="s">"base.html"</span><span class="p">,</span> <span class="s">'''</span>
+<span class="s">    <html><body>${self.next()}</body></html></span>
+<span class="s">'''</span><span class="p">)</span>
+<span class="n">lookup</span><span class="o">.</span><span class="n">put_string</span><span class="p">(</span><span class="s">"hello.html"</span><span class="p">,</span> <span class="s">'''</span>
+<span class="s">    <</span><span class="si">%i</span><span class="s">nclude file='base.html'/></span>
+
+<span class="s">    Hello, world !</span>
+<span class="s">'''</span><span class="p">)</span>
+</pre></div>
+</div>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>directories</strong> – A list of directory names which will be
+searched for a particular template URI. The URI is appended
+to each directory and the filesystem checked.</li>
+<li><strong>collection_size</strong> – Approximate size of the collection used
+to store templates. If left at its default of <tt class="docutils literal"><span class="pre">-1</span></tt>, the size
+is unbounded, and a plain Python dictionary is used to
+relate URI strings to <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> instances.
+Otherwise, a least-recently-used cache object is used which
+will maintain the size of the collection approximately to
+the number given.</li>
+<li><strong>filesystem_checks</strong> – When at its default value of <tt class="docutils literal"><span class="pre">True</span></tt>,
+each call to <a class="reference internal" href="#mako.lookup.TemplateLookup.get_template" title="mako.lookup.TemplateLookup.get_template"><tt class="xref py py-meth docutils literal"><span class="pre">TemplateLookup.get_template()</span></tt></a> will
+compare the filesystem last modified time to the time in
+which an existing <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object was created.
+This allows the <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> to regenerate a
+new <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> whenever the original source has
+been updated. Set this to <tt class="docutils literal"><span class="pre">False</span></tt> for a very minor
+performance increase.</li>
+<li><strong>modulename_callable</strong> – A callable which, when present,
+is passed the path of the source file as well as the
+requested URI, and then returns the full path of the
+generated Python module file. This is used to inject
+alternate schemes for Python module location. If left at
+its default of <tt class="docutils literal"><span class="pre">None</span></tt>, the built in system of generation
+based on <tt class="docutils literal"><span class="pre">module_directory</span></tt> plus <tt class="docutils literal"><span class="pre">uri</span></tt> is used.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<p>All other keyword parameters available for
+<a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> are mirrored here. When new
+<a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> objects are created, the keywords
+established with this <a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a> are passed on
+to each new <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a>.</p>
+<dl class="method">
+<dt id="mako.lookup.TemplateLookup.adjust_uri">
+<tt class="descname">adjust_uri</tt><big>(</big><em>uri</em>, <em>relativeto</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateLookup.adjust_uri" title="Permalink to this definition">¶</a></dt>
+<dd><p>Adjust the given <tt class="docutils literal"><span class="pre">uri</span></tt> based on the given relative URI.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.lookup.TemplateLookup.filename_to_uri">
+<tt class="descname">filename_to_uri</tt><big>(</big><em>filename</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateLookup.filename_to_uri" title="Permalink to this definition">¶</a></dt>
+<dd><p>Convert the given <tt class="docutils literal"><span class="pre">filename</span></tt> to a URI relative to
+this <a class="reference internal" href="#mako.lookup.TemplateCollection" title="mako.lookup.TemplateCollection"><tt class="xref py py-class docutils literal"><span class="pre">TemplateCollection</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.lookup.TemplateLookup.get_template">
+<tt class="descname">get_template</tt><big>(</big><em>uri</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateLookup.get_template" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return a <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object corresponding to the given
+<tt class="docutils literal"><span class="pre">uri</span></tt>.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">The <tt class="docutils literal"><span class="pre">relativeto</span></tt> argument is not supported here at the moment.</p>
+</div>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.lookup.TemplateLookup.put_string">
+<tt class="descname">put_string</tt><big>(</big><em>uri</em>, <em>text</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateLookup.put_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>Place a new <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object into this
+<a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>, based on the given string of
+<tt class="docutils literal"><span class="pre">text</span></tt>.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="mako.lookup.TemplateLookup.put_template">
+<tt class="descname">put_template</tt><big>(</big><em>uri</em>, <em>template</em><big>)</big><a class="headerlink" href="#mako.lookup.TemplateLookup.put_template" title="Permalink to this definition">¶</a></dt>
+<dd><p>Place a new <a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object into this
+<a class="reference internal" href="#mako.lookup.TemplateLookup" title="mako.lookup.TemplateLookup"><tt class="xref py py-class docutils literal"><span class="pre">TemplateLookup</span></tt></a>, based on the given
+<a class="reference internal" href="#mako.template.Template" title="mako.template.Template"><tt class="xref py py-class docutils literal"><span class="pre">Template</span></tt></a> object.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="mako.exceptions.RichTraceback">
+<em class="property">class </em><tt class="descclassname">mako.exceptions.</tt><tt class="descname">RichTraceback</tt><big>(</big><em>error=None</em>, <em>traceback=None</em><big>)</big><a class="headerlink" href="#mako.exceptions.RichTraceback" title="Permalink to this definition">¶</a></dt>
+<dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p>
+<p>Pull the current exception from the <tt class="docutils literal"><span class="pre">sys</span></tt> traceback and extracts
+Mako-specific template information.</p>
+<p>See the usage examples in <a class="reference internal" href="#handling-exceptions"><em>Handling Exceptions</em></a>.</p>
+<dl class="attribute">
+<dt id="RichTraceback.error">
+<tt class="descname">error</tt><a class="headerlink" href="#RichTraceback.error" title="Permalink to this definition">¶</a></dt>
+<dd><p>the exception instance.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="RichTraceback.message">
+<tt class="descname">message</tt><a class="headerlink" href="#RichTraceback.message" title="Permalink to this definition">¶</a></dt>
+<dd><p>the exception error message as unicode.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="RichTraceback.source">
+<tt class="descname">source</tt><a class="headerlink" href="#RichTraceback.source" title="Permalink to this definition">¶</a></dt>
+<dd><p>source code of the file where the error occurred.
+If the error occurred within a compiled template,
+this is the template source.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="RichTraceback.lineno">
+<tt class="descname">lineno</tt><a class="headerlink" href="#RichTraceback.lineno" title="Permalink to this definition">¶</a></dt>
+<dd><p>line number where the error occurred.  If the error
+occurred within a compiled template, the line number
+is adjusted to that of the template source.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="RichTraceback.records">
+<tt class="descname">records</tt><a class="headerlink" href="#RichTraceback.records" title="Permalink to this definition">¶</a></dt>
+<dd><p>a list of 8-tuples containing the original
+python traceback elements, plus the
+filename, line number, source line, and full template source
+for the traceline mapped back to its originating source
+template, if any for that traceline (else the fields are <tt class="docutils literal"><span class="pre">None</span></tt>).</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="RichTraceback.reverse_records">
+<tt class="descname">reverse_records</tt><a class="headerlink" href="#RichTraceback.reverse_records" title="Permalink to this definition">¶</a></dt>
+<dd><p>the list of records in reverse
+traceback – a list of 4-tuples, in the same format as a regular
+python traceback, with template-corresponding
+traceback records replacing the originals.</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="RichTraceback.reverse_traceback">
+<tt class="descname">reverse_traceback</tt><a class="headerlink" href="#RichTraceback.reverse_traceback" title="Permalink to this definition">¶</a></dt>
+<dd><p>the traceback list in reverse.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="mako.exceptions.html_error_template">
+<tt class="descclassname">mako.exceptions.</tt><tt class="descname">html_error_template</tt><big>(</big><big>)</big><a class="headerlink" href="#mako.exceptions.html_error_template" title="Permalink to this definition">¶</a></dt>
+<dd><p>Provides a template that renders a stack trace in an HTML format,
+providing an excerpt of code as well as substituting source template
+filenames, line numbers and code for that of the originating source
+template, as applicable.</p>
+<p>The template’s default <tt class="docutils literal"><span class="pre">encoding_errors</span></tt> value is <tt class="docutils literal"><span class="pre">'htmlentityreplace'</span></tt>. The
+template has two options. With the <tt class="docutils literal"><span class="pre">full</span></tt> option disabled, only a section of
+an HTML document is returned. With the <tt class="docutils literal"><span class="pre">css</span></tt> option disabled, the default
+stylesheet won’t be included.</p>
+</dd></dl>
+
+<dl class="function">
+<dt id="mako.exceptions.text_error_template">
+<tt class="descclassname">mako.exceptions.</tt><tt class="descname">text_error_template</tt><big>(</big><em>lookup=None</em><big>)</big><a class="headerlink" href="#mako.exceptions.text_error_template" title="Permalink to this definition">¶</a></dt>
+<dd><p>Provides a template that renders a stack trace in a similar format to
+the Python interpreter, substituting source template filenames, line
+numbers and code for that of the originating source template, as
+applicable.</p>
+</dd></dl>
+
+</div>
+</div>
+
+    </div>
+
+</div>
+
+<div id="docs-bottom-navigation" class="docs-navigation-links">
+        Previous:
+        <a href="index.html" title="previous chapter">Table of Contents</a>
+        Next:
+        <a href="syntax.html" title="next chapter">Syntax</a>
+
+    <div id="docs-copyright">
+        © Copyright the Mako authors and contributors.
+        Documentation generated using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 
+        with Mako templates.
+    </div>
+</div>
+
+</div>
+
+<div class="clearfix">
+
+<hr/>
+
+<div class="copyright">Website content copyright © by Michael Bayer.
+    All rights reserved.  Mako and its documentation are licensed
+    under the MIT license.  mike(&)zzzcomputing.com</div>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/lib3/Mako-0.7.3/examples/bench/basic.py b/lib3/Mako-0.7.3/examples/bench/basic.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/bench/basic.py
@@ -0,0 +1,191 @@
+# basic.py - basic benchmarks adapted from Genshi
+# Copyright (C) 2006 Edgewall Software
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#  3. The name of the author may not be used to endorse or promote
+#     products derived from this software without specific prior
+#     written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from cgi import escape
+import os
+try:
+    from io import StringIO
+except ImportError:
+    from io import StringIO
+import sys
+import timeit
+
+def u(stringlit):
+    if sys.version_info >= (3,):
+        return stringlit
+    else:
+        return stringlit.decode('latin1')
+
+__all__ = ['mako', 'mako_inheritance', 'jinja2', 'jinja2_inheritance',
+            'cheetah', 'django', 'myghty', 'genshi', 'kid']
+
+# Templates content and constants
+TITLE = 'Just a test'
+USER = 'joe'
+ITEMS = ['Number %d' % num for num in range(1, 15)]
+U_ITEMS = [u(item) for item in ITEMS]
+
+def genshi(dirname, verbose=False):
+    from genshi.template import TemplateLoader
+    loader = TemplateLoader([dirname], auto_reload=False)
+    template = loader.load('template.html')
+    def render():
+        data = dict(title=TITLE, user=USER, items=ITEMS)
+        return template.generate(**data).render('xhtml')
+
+    if verbose:
+        print((render()))
+    return render
+
+def myghty(dirname, verbose=False):
+    from myghty import interp
+    interpreter = interp.Interpreter(component_root=dirname)
+    def render():
+        data = dict(title=TITLE, user=USER, items=ITEMS)
+        buffer = StringIO()
+        interpreter.execute("template.myt", request_args=data, out_buffer=buffer)
+        return buffer.getvalue()
+    if verbose:
+        print((render()))
+    return render
+
+def mako(dirname, verbose=False):
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+    disable_unicode = (sys.version_info < (3,))
+    lookup = TemplateLookup(directories=[dirname], filesystem_checks=False, disable_unicode=disable_unicode)
+    template = lookup.get_template('template.html')
+    def render():
+        return template.render(title=TITLE, user=USER, list_items=U_ITEMS)
+    if verbose:
+        print((template.code + " " + render()))
+    return render
+mako_inheritance = mako
+
+def jinja2(dirname, verbose=False):
+    from jinja2 import Environment, FileSystemLoader
+    env = Environment(loader=FileSystemLoader(dirname))
+    template = env.get_template('template.html')
+    def render():
+        return template.render(title=TITLE, user=USER, list_items=U_ITEMS)
+    if verbose:
+        print((render()))
+    return render
+jinja2_inheritance = jinja2
+
+def cheetah(dirname, verbose=False):
+    from Cheetah.Template import Template
+    filename = os.path.join(dirname, 'template.tmpl')
+    template = Template(file=filename)
+    def render():
+        template.__dict__.update({'title': TITLE, 'user': USER,
+                                  'list_items': U_ITEMS})
+        return template.respond()
+
+    if verbose:
+        print((dir(template)))
+        print((template.generatedModuleCode()))
+        print((render()))
+    return render
+
+def django(dirname, verbose=False):
+    from django.conf import settings
+    settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')])
+    from django import template, templatetags
+    from django.template import loader
+    templatetags.__path__.append(os.path.join(dirname, 'templatetags'))
+    tmpl = loader.get_template('template.html')
+
+    def render():
+        data = {'title': TITLE, 'user': USER, 'items': ITEMS}
+        return tmpl.render(template.Context(data))
+
+    if verbose:
+        print((render()))
+    return render
+
+def kid(dirname, verbose=False):
+    import kid
+    kid.path = kid.TemplatePath([dirname])
+    template = kid.Template(file='template.kid')
+    def render():
+        template = kid.Template(file='template.kid',
+                                title=TITLE, user=USER, items=ITEMS)
+        return template.serialize(output='xhtml')
+
+    if verbose:
+        print((render()))
+    return render
+
+
+def run(engines, number=2000, verbose=False):
+    basepath = os.path.abspath(os.path.dirname(__file__))
+    for engine in engines:
+        dirname = os.path.join(basepath, engine)
+        if verbose:
+            print(('%s:' % engine.capitalize()))
+            print('--------------------------------------------------------')
+        else:
+            sys.stdout.write('%s:' % engine.capitalize())
+        t = timeit.Timer(setup='from __main__ import %s; render = %s(r"%s", %s)'
+                                       % (engine, engine, dirname, verbose),
+                                 stmt='render()')
+
+        time = t.timeit(number=number) / number
+        if verbose:
+            print('--------------------------------------------------------')
+        print(('%.2f ms' % (1000 * time)))
+        if verbose:
+            print('--------------------------------------------------------')
+
+
+if __name__ == '__main__':
+    engines = [arg for arg in sys.argv[1:] if arg[0] != '-']
+    if not engines:
+        engines = __all__
+
+    verbose = '-v' in sys.argv
+
+    if '-p' in sys.argv:
+        try:
+            import hotshot, hotshot.stats
+            prof = hotshot.Profile("template.prof")
+            benchtime = prof.runcall(run, engines, number=100, verbose=verbose)
+            stats = hotshot.stats.load("template.prof")
+        except ImportError:
+            import cProfile, pstats
+            stmt = "run(%r, number=%r, verbose=%r)" % (engines, 1000, verbose)
+            cProfile.runctx(stmt, globals(), {}, "template.prof")
+            stats = pstats.Stats("template.prof")
+        stats.strip_dirs()
+        stats.sort_stats('time', 'calls')
+        stats.print_stats()
+    else:
+        run(engines, verbose=verbose)
diff --git a/lib3/Mako-0.7.3/examples/bench/cheetah/footer.tmpl b/lib3/Mako-0.7.3/examples/bench/cheetah/footer.tmpl
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/bench/cheetah/footer.tmpl
@@ -0,0 +1,2 @@
+<div id="footer">
+</div>
diff --git a/lib3/Mako-0.7.3/examples/bench/cheetah/header.tmpl b/lib3/Mako-0.7.3/examples/bench/cheetah/header.tmpl
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/bench/cheetah/header.tmpl
@@ -0,0 +1,5 @@
+<div id="header">
+  <h1>$title</h1>
+</div>
+
+
diff --git a/lib3/Mako-0.7.3/examples/bench/cheetah/template.tmpl b/lib3/Mako-0.7.3/examples/bench/cheetah/template.tmpl
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/bench/cheetah/template.tmpl
@@ -0,0 +1,31 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+  <head>
+    <title>${title}</title>
+  </head>
+  <body>
+
+      #def greeting(name)
+      <p>hello ${name}!</p>
+      #end def
+ 
+    #include "cheetah/header.tmpl"
+
+    $greeting($user)
+    $greeting('me')
+    $greeting('world')
+ 
+    <h2>Loop</h2>
+    #if $list_items
+      <ul>
+        #for $list_item in $list_items
+          <li #if $list_item is $list_items[-1] then "class='last'" else ""#>$list_item</li>
+        #end for
+      </ul>
+    #end if
+
+    #include "cheetah/footer.tmpl"
+  </body>
+</html>
diff --git a/lib3/Mako-0.7.3/examples/bench/django/templatetags/__init__.py b/lib3/Mako-0.7.3/examples/bench/django/templatetags/__init__.py
new file mode 100644
diff --git a/lib3/Mako-0.7.3/examples/bench/django/templatetags/bench.py b/lib3/Mako-0.7.3/examples/bench/django/templatetags/bench.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/bench/django/templatetags/bench.py
@@ -0,0 +1,8 @@
+from django.template import Library, Node, resolve_variable
+from django.utils.html import escape
+
+register = Library()
+
+def greeting(name):
+    return 'Hello, %s!' % escape(name)
+greeting = register.simple_tag(greeting)
diff --git a/lib3/Mako-0.7.3/examples/bench/kid/base.kid b/lib3/Mako-0.7.3/examples/bench/kid/base.kid
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/bench/kid/base.kid
@@ -0,0 +1,15 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://purl.org/kid/ns#">
+
+  <p py:def="greeting(name)">
+    Hello, ${name}!
+  </p>
+
+  <body py:match="item.tag == '{http://www.w3.org/1999/xhtml}body'" py:strip="">
+    <div id="header">
+      <h1>${title}</h1>
+    </div>
+    ${item}
+    <div id="footer" />
+  </body>
+</html>
diff --git a/lib3/Mako-0.7.3/examples/bench/kid/template.kid b/lib3/Mako-0.7.3/examples/bench/kid/template.kid
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/bench/kid/template.kid
@@ -0,0 +1,22 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://purl.org/kid/ns#"
+      py:extends="'base.kid'"
+      lang="en">
+  <head>
+    <title>${title}</title>
+  </head>
+  <body>
+    <div>${greeting(user)}</div>
+    <div>${greeting('me')}</div>
+    <div>${greeting('world')}</div>
+ 
+    <h2>Loop</h2>
+    <ul py:if="items">
+      <li py:for="idx, item in enumerate(items)" py:content="item"
+          class="${idx + 1 == len(items) and 'last' or None}" />
+    </ul>
+  </body>
+</html>
diff --git a/lib3/Mako-0.7.3/examples/bench/myghty/base.myt b/lib3/Mako-0.7.3/examples/bench/myghty/base.myt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/bench/myghty/base.myt
@@ -0,0 +1,29 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+<%args scope="request">
+    title
+</%args>
+
+<& REQUEST:header &>
+
+<body>
+<div id="header">
+  <h1><% title %></h1>
+</div>
+
+% m.call_next()
+
+<div id="footer"></div>
+
+</body>
+</html>
+
+
+<%method greeting>
+<%args>
+   name
+</%args>
+Hello, <% name | h %>
+</%method>
diff --git a/lib3/Mako-0.7.3/examples/bench/myghty/template.myt b/lib3/Mako-0.7.3/examples/bench/myghty/template.myt
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/bench/myghty/template.myt
@@ -0,0 +1,30 @@
+<%flags>inherit="base.myt"</%flags>
+<%args>
+	title
+	items
+	user
+</%args>
+
+<%method header>
+    <%args scope="request">
+    title
+    </%args>
+<head>
+  <title><% title %></title>
+</head>
+</%method>
+
+  <div><& base.myt:greeting, name=user &></div>
+  <div><& base.myt:greeting, name="me"&></div>
+  <div><& base.myt:greeting, name="world" &></div>
+
+  <h2>Loop</h2>
+%if items:
+      <ul>
+%	for i, item in enumerate(items):
+  <li <% i+1==len(items) and "class='last'" or ""%>><% item %></li>
+%
+      </ul>
+%
+
+ 
diff --git a/lib3/Mako-0.7.3/examples/wsgi/run_wsgi.py b/lib3/Mako-0.7.3/examples/wsgi/run_wsgi.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/examples/wsgi/run_wsgi.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+import cgi, re, os, posixpath, mimetypes
+from mako.lookup import TemplateLookup
+from mako import exceptions
+
+root = './'
+port = 8000
+error_style = 'html' # select 'text' for plaintext error reporting
+
+lookup = TemplateLookup(directories=[root + 'templates', root + 'htdocs'], filesystem_checks=True, module_directory='./modules')
+
+def serve(environ, start_response):
+    """serves requests using the WSGI callable interface."""
+    fieldstorage = cgi.FieldStorage(
+            fp = environ['wsgi.input'],
+            environ = environ,
+            keep_blank_values = True
+    )
+    d = dict([(k, getfield(fieldstorage[k])) for k in fieldstorage])
+
+    uri = environ.get('PATH_INFO', '/')
+    if not uri:
+        uri = '/index.html'
+    else:
+        uri = re.sub(r'^/$', '/index.html', uri)
+
+    if re.match(r'.*\.html$', uri):
+        try:
+            template = lookup.get_template(uri)
+            start_response("200 OK", [('Content-type','text/html')])
+            return [template.render(**d)]
+        except exceptions.TopLevelLookupException:
+            start_response("404 Not Found", [])
+            return ["Cant find template '%s'" % uri]
+        except:
+            if error_style == 'text':
+                start_response("200 OK", [('Content-type','text/plain')])
+                return [exceptions.text_error_template().render()]
+            else:
+                start_response("200 OK", [('Content-type','text/html')])
+                return [exceptions.html_error_template().render()]
+    else:
+        u = re.sub(r'^\/+', '', uri)
+        filename = os.path.join(root, u)
+        start_response("200 OK", [('Content-type',guess_type(uri))])
+        return [file(filename).read()]
+ 
+def getfield(f):
+    """convert values from cgi.Field objects to plain values."""
+    if isinstance(f, list):
+        return [getfield(x) for x in f]
+    else:
+        return f.value
+
+extensions_map = mimetypes.types_map.copy()
+extensions_map.update({
+'': 'text/html', # Default
+})
+
+def guess_type(path):
+    """return a mimetype for the given path based on file extension."""
+    base, ext = posixpath.splitext(path)
+    if ext in extensions_map:
+        return extensions_map[ext]
+    ext = ext.lower()
+    if ext in extensions_map:
+        return extensions_map[ext]
+    else:
+        return extensions_map['']
+ 
+if __name__ == '__main__':
+    import wsgiref.simple_server
+    server = wsgiref.simple_server.make_server('', port, serve)
+    print("Server listening on port %d" % port)
+    server.serve_forever()
+
+
diff --git a/lib3/Mako-0.7.3/mako/__init__.py b/lib3/Mako-0.7.3/mako/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/__init__.py
@@ -0,0 +1,9 @@
+# mako/__init__.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+
+__version__ = '0.7.3'
+
diff --git a/lib3/Mako-0.7.3/mako/_ast_util.py b/lib3/Mako-0.7.3/mako/_ast_util.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/_ast_util.py
@@ -0,0 +1,839 @@
+# mako/_ast_util.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""
+    ast
+    ~~~
+
+    The `ast` module helps Python applications to process trees of the Python
+    abstract syntax grammar.  The abstract syntax itself might change with
+    each Python release; this module helps to find out programmatically what
+    the current grammar looks like and allows modifications of it.
+
+    An abstract syntax tree can be generated by passing `ast.PyCF_ONLY_AST` as
+    a flag to the `compile()` builtin function or by using the `parse()`
+    function from this module.  The result will be a tree of objects whose
+    classes all inherit from `ast.AST`.
+
+    A modified abstract syntax tree can be compiled into a Python code object
+    using the built-in `compile()` function.
+
+    Additionally various helper functions are provided that make working with
+    the trees simpler.  The main intention of the helper functions and this
+    module in general is to provide an easy to use interface for libraries
+    that work tightly with the python syntax (template engines for example).
+
+
+    :copyright: Copyright 2008 by Armin Ronacher.
+    :license: Python License.
+"""
+from _ast import *
+
+
+BOOLOP_SYMBOLS = {
+    And:        'and',
+    Or:         'or'
+}
+
+BINOP_SYMBOLS = {
+    Add:        '+',
+    Sub:        '-',
+    Mult:       '*',
+    Div:        '/',
+    FloorDiv:   '//',
+    Mod:        '%',
+    LShift:     '<<',
+    RShift:     '>>',
+    BitOr:      '|',
+    BitAnd:     '&',
+    BitXor:     '^'
+}
+
+CMPOP_SYMBOLS = {
+    Eq:         '==',
+    Gt:         '>',
+    GtE:        '>=',
+    In:         'in',
+    Is:         'is',
+    IsNot:      'is not',
+    Lt:         '<',
+    LtE:        '<=',
+    NotEq:      '!=',
+    NotIn:      'not in'
+}
+
+UNARYOP_SYMBOLS = {
+    Invert:     '~',
+    Not:        'not',
+    UAdd:       '+',
+    USub:       '-'
+}
+
+ALL_SYMBOLS = {}
+ALL_SYMBOLS.update(BOOLOP_SYMBOLS)
+ALL_SYMBOLS.update(BINOP_SYMBOLS)
+ALL_SYMBOLS.update(CMPOP_SYMBOLS)
+ALL_SYMBOLS.update(UNARYOP_SYMBOLS)
+
+
+def parse(expr, filename='<unknown>', mode='exec'):
+    """Parse an expression into an AST node."""
+    return compile(expr, filename, mode, PyCF_ONLY_AST)
+
+
+def to_source(node, indent_with=' ' * 4):
+    """
+    This function can convert a node tree back into python sourcecode.  This
+    is useful for debugging purposes, especially if you're dealing with custom
+    asts not generated by python itself.
+
+    It could be that the sourcecode is evaluable when the AST itself is not
+    compilable / evaluable.  The reason for this is that the AST contains some
+    more data than regular sourcecode does, which is dropped during
+    conversion.
+
+    Each level of indentation is replaced with `indent_with`.  Per default this
+    parameter is equal to four spaces as suggested by PEP 8, but it might be
+    adjusted to match the application's styleguide.
+    """
+    generator = SourceGenerator(indent_with)
+    generator.visit(node)
+    return ''.join(generator.result)
+
+
+def dump(node):
+    """
+    A very verbose representation of the node passed.  This is useful for
+    debugging purposes.
+    """
+    def _format(node):
+        if isinstance(node, AST):
+            return '%s(%s)' % (node.__class__.__name__,
+                               ', '.join('%s=%s' % (a, _format(b))
+                                         for a, b in iter_fields(node)))
+        elif isinstance(node, list):
+            return '[%s]' % ', '.join(_format(x) for x in node)
+        return repr(node)
+    if not isinstance(node, AST):
+        raise TypeError('expected AST, got %r' % node.__class__.__name__)
+    return _format(node)
+
+
+def copy_location(new_node, old_node):
+    """
+    Copy the source location hint (`lineno` and `col_offset`) from the
+    old to the new node if possible and return the new one.
+    """
+    for attr in 'lineno', 'col_offset':
+        if attr in old_node._attributes and attr in new_node._attributes \
+           and hasattr(old_node, attr):
+            setattr(new_node, attr, getattr(old_node, attr))
+    return new_node
+
+
+def fix_missing_locations(node):
+    """
+    Some nodes require a line number and the column offset.  Without that
+    information the compiler will abort the compilation.  Because it can be
+    a dull task to add appropriate line numbers and column offsets when
+    adding new nodes this function can help.  It copies the line number and
+    column offset of the parent node to the child nodes without this
+    information.
+
+    Unlike `copy_location` this works recursive and won't touch nodes that
+    already have a location information.
+    """
+    def _fix(node, lineno, col_offset):
+        if 'lineno' in node._attributes:
+            if not hasattr(node, 'lineno'):
+                node.lineno = lineno
+            else:
+                lineno = node.lineno
+        if 'col_offset' in node._attributes:
+            if not hasattr(node, 'col_offset'):
+                node.col_offset = col_offset
+            else:
+                col_offset = node.col_offset
+        for child in iter_child_nodes(node):
+            _fix(child, lineno, col_offset)
+    _fix(node, 1, 0)
+    return node
+
+
+def increment_lineno(node, n=1):
+    """
+    Increment the line numbers of all nodes by `n` if they have line number
+    attributes.  This is useful to "move code" to a different location in a
+    file.
+    """
+    for node in zip((node,), walk(node)):
+        if 'lineno' in node._attributes:
+            node.lineno = getattr(node, 'lineno', 0) + n
+
+
+def iter_fields(node):
+    """Iterate over all fields of a node, only yielding existing fields."""
+    # CPython 2.5 compat
+    if not hasattr(node, '_fields') or not node._fields:
+        return
+    for field in node._fields:
+        try:
+            yield field, getattr(node, field)
+        except AttributeError:
+            pass
+
+
+def get_fields(node):
+    """Like `iter_fiels` but returns a dict."""
+    return dict(iter_fields(node))
+
+
+def iter_child_nodes(node):
+    """Iterate over all child nodes or a node."""
+    for name, field in iter_fields(node):
+        if isinstance(field, AST):
+            yield field
+        elif isinstance(field, list):
+            for item in field:
+                if isinstance(item, AST):
+                    yield item
+
+
+def get_child_nodes(node):
+    """Like `iter_child_nodes` but returns a list."""
+    return list(iter_child_nodes(node))
+
+
+def get_compile_mode(node):
+    """
+    Get the mode for `compile` of a given node.  If the node is not a `mod`
+    node (`Expression`, `Module` etc.) a `TypeError` is thrown.
+    """
+    if not isinstance(node, mod):
+        raise TypeError('expected mod node, got %r' % node.__class__.__name__)
+    return {
+        Expression:     'eval',
+        Interactive:    'single'
+    }.get(node.__class__, 'expr')
+
+
+def get_docstring(node):
+    """
+    Return the docstring for the given node or `None` if no docstring can be
+    found.  If the node provided does not accept docstrings a `TypeError`
+    will be raised.
+    """
+    if not isinstance(node, (FunctionDef, ClassDef, Module)):
+        raise TypeError("%r can't have docstrings" % node.__class__.__name__)
+    if node.body and isinstance(node.body[0], Str):
+        return node.body[0].s
+
+
+def walk(node):
+    """
+    Iterate over all nodes.  This is useful if you only want to modify nodes in
+    place and don't care about the context or the order the nodes are returned.
+    """
+    from collections import deque
+    todo = deque([node])
+    while todo:
+        node = todo.popleft()
+        todo.extend(iter_child_nodes(node))
+        yield node
+
+
+class NodeVisitor(object):
+    """
+    Walks the abstract syntax tree and call visitor functions for every node
+    found.  The visitor functions may return values which will be forwarded
+    by the `visit` method.
+
+    Per default the visitor functions for the nodes are ``'visit_'`` +
+    class name of the node.  So a `TryFinally` node visit function would
+    be `visit_TryFinally`.  This behavior can be changed by overriding
+    the `get_visitor` function.  If no visitor function exists for a node
+    (return value `None`) the `generic_visit` visitor is used instead.
+
+    Don't use the `NodeVisitor` if you want to apply changes to nodes during
+    traversing.  For this a special visitor exists (`NodeTransformer`) that
+    allows modifications.
+    """
+
+    def get_visitor(self, node):
+        """
+        Return the visitor function for this node or `None` if no visitor
+        exists for this node.  In that case the generic visit function is
+        used instead.
+        """
+        method = 'visit_' + node.__class__.__name__
+        return getattr(self, method, None)
+
+    def visit(self, node):
+        """Visit a node."""
+        f = self.get_visitor(node)
+        if f is not None:
+            return f(node)
+        return self.generic_visit(node)
+
+    def generic_visit(self, node):
+        """Called if no explicit visitor function exists for a node."""
+        for field, value in iter_fields(node):
+            if isinstance(value, list):
+                for item in value:
+                    if isinstance(item, AST):
+                        self.visit(item)
+            elif isinstance(value, AST):
+                self.visit(value)
+
+
+class NodeTransformer(NodeVisitor):
+    """
+    Walks the abstract syntax tree and allows modifications of nodes.
+
+    The `NodeTransformer` will walk the AST and use the return value of the
+    visitor functions to replace or remove the old node.  If the return
+    value of the visitor function is `None` the node will be removed
+    from the previous location otherwise it's replaced with the return
+    value.  The return value may be the original node in which case no
+    replacement takes place.
+
+    Here an example transformer that rewrites all `foo` to `data['foo']`::
+
+        class RewriteName(NodeTransformer):
+
+            def visit_Name(self, node):
+                return copy_location(Subscript(
+                    value=Name(id='data', ctx=Load()),
+                    slice=Index(value=Str(s=node.id)),
+                    ctx=node.ctx
+                ), node)
+
+    Keep in mind that if the node you're operating on has child nodes
+    you must either transform the child nodes yourself or call the generic
+    visit function for the node first.
+
+    Nodes that were part of a collection of statements (that applies to
+    all statement nodes) may also return a list of nodes rather than just
+    a single node.
+
+    Usually you use the transformer like this::
+
+        node = YourTransformer().visit(node)
+    """
+
+    def generic_visit(self, node):
+        for field, old_value in iter_fields(node):
+            old_value = getattr(node, field, None)
+            if isinstance(old_value, list):
+                new_values = []
+                for value in old_value:
+                    if isinstance(value, AST):
+                        value = self.visit(value)
+                        if value is None:
+                            continue
+                        elif not isinstance(value, AST):
+                            new_values.extend(value)
+                            continue
+                    new_values.append(value)
+                old_value[:] = new_values
+            elif isinstance(old_value, AST):
+                new_node = self.visit(old_value)
+                if new_node is None:
+                    delattr(node, field)
+                else:
+                    setattr(node, field, new_node)
+        return node
+
+
+class SourceGenerator(NodeVisitor):
+    """
+    This visitor is able to transform a well formed syntax tree into python
+    sourcecode.  For more details have a look at the docstring of the
+    `node_to_source` function.
+    """
+
+    def __init__(self, indent_with):
+        self.result = []
+        self.indent_with = indent_with
+        self.indentation = 0
+        self.new_lines = 0
+
+    def write(self, x):
+        if self.new_lines:
+            if self.result:
+                self.result.append('\n' * self.new_lines)
+            self.result.append(self.indent_with * self.indentation)
+            self.new_lines = 0
+        self.result.append(x)
+
+    def newline(self, n=1):
+        self.new_lines = max(self.new_lines, n)
+
+    def body(self, statements):
+        self.new_line = True
+        self.indentation += 1
+        for stmt in statements:
+            self.visit(stmt)
+        self.indentation -= 1
+
+    def body_or_else(self, node):
+        self.body(node.body)
+        if node.orelse:
+            self.newline()
+            self.write('else:')
+            self.body(node.orelse)
+
+    def signature(self, node):
+        want_comma = []
+        def write_comma():
+            if want_comma:
+                self.write(', ')
+            else:
+                want_comma.append(True)
+
+        padding = [None] * (len(node.args) - len(node.defaults))
+        for arg, default in zip(node.args, padding + node.defaults):
+            write_comma()
+            self.visit(arg)
+            if default is not None:
+                self.write('=')
+                self.visit(default)
+        if node.vararg is not None:
+            write_comma()
+            self.write('*' + node.vararg)
+        if node.kwarg is not None:
+            write_comma()
+            self.write('**' + node.kwarg)
+
+    def decorators(self, node):
+        for decorator in node.decorator_list:
+            self.newline()
+            self.write('@')
+            self.visit(decorator)
+
+    # Statements
+
+    def visit_Assign(self, node):
+        self.newline()
+        for idx, target in enumerate(node.targets):
+            if idx:
+                self.write(', ')
+            self.visit(target)
+        self.write(' = ')
+        self.visit(node.value)
+
+    def visit_AugAssign(self, node):
+        self.newline()
+        self.visit(node.target)
+        self.write(BINOP_SYMBOLS[type(node.op)] + '=')
+        self.visit(node.value)
+
+    def visit_ImportFrom(self, node):
+        self.newline()
+        self.write('from %s%s import ' % ('.' * node.level, node.module))
+        for idx, item in enumerate(node.names):
+            if idx:
+                self.write(', ')
+            self.write(item)
+
+    def visit_Import(self, node):
+        self.newline()
+        for item in node.names:
+            self.write('import ')
+            self.visit(item)
+
+    def visit_Expr(self, node):
+        self.newline()
+        self.generic_visit(node)
+
+    def visit_FunctionDef(self, node):
+        self.newline(n=2)
+        self.decorators(node)
+        self.newline()
+        self.write('def %s(' % node.name)
+        self.signature(node.args)
+        self.write('):')
+        self.body(node.body)
+
+    def visit_ClassDef(self, node):
+        have_args = []
+        def paren_or_comma():
+            if have_args:
+                self.write(', ')
+            else:
+                have_args.append(True)
+                self.write('(')
+
+        self.newline(n=3)
+        self.decorators(node)
+        self.newline()
+        self.write('class %s' % node.name)
+        for base in node.bases:
+            paren_or_comma()
+            self.visit(base)
+        # XXX: the if here is used to keep this module compatible
+        #      with python 2.6.
+        if hasattr(node, 'keywords'):
+            for keyword in node.keywords:
+                paren_or_comma()
+                self.write(keyword.arg + '=')
+                self.visit(keyword.value)
+            if node.starargs is not None:
+                paren_or_comma()
+                self.write('*')
+                self.visit(node.starargs)
+            if node.kwargs is not None:
+                paren_or_comma()
+                self.write('**')
+                self.visit(node.kwargs)
+        self.write(have_args and '):' or ':')
+        self.body(node.body)
+
+    def visit_If(self, node):
+        self.newline()
+        self.write('if ')
+        self.visit(node.test)
+        self.write(':')
+        self.body(node.body)
+        while True:
+            else_ = node.orelse
+            if len(else_) == 1 and isinstance(else_[0], If):
+                node = else_[0]
+                self.newline()
+                self.write('elif ')
+                self.visit(node.test)
+                self.write(':')
+                self.body(node.body)
+            else:
+                self.newline()
+                self.write('else:')
+                self.body(else_)
+                break
+
+    def visit_For(self, node):
+        self.newline()
+        self.write('for ')
+        self.visit(node.target)
+        self.write(' in ')
+        self.visit(node.iter)
+        self.write(':')
+        self.body_or_else(node)
+
+    def visit_While(self, node):
+        self.newline()
+        self.write('while ')
+        self.visit(node.test)
+        self.write(':')
+        self.body_or_else(node)
+
+    def visit_With(self, node):
+        self.newline()
+        self.write('with ')
+        self.visit(node.context_expr)
+        if node.optional_vars is not None:
+            self.write(' as ')
+            self.visit(node.optional_vars)
+        self.write(':')
+        self.body(node.body)
+
+    def visit_Pass(self, node):
+        self.newline()
+        self.write('pass')
+
+    def visit_Print(self, node):
+        # XXX: python 2.6 only
+        self.newline()
+        self.write('print ')
+        want_comma = False
+        if node.dest is not None:
+            self.write(' >> ')
+            self.visit(node.dest)
+            want_comma = True
+        for value in node.values:
+            if want_comma:
+                self.write(', ')
+            self.visit(value)
+            want_comma = True
+        if not node.nl:
+            self.write(',')
+
+    def visit_Delete(self, node):
+        self.newline()
+        self.write('del ')
+        for idx, target in enumerate(node):
+            if idx:
+                self.write(', ')
+            self.visit(target)
+
+    def visit_TryExcept(self, node):
+        self.newline()
+        self.write('try:')
+        self.body(node.body)
+        for handler in node.handlers:
+            self.visit(handler)
+
+    def visit_TryFinally(self, node):
+        self.newline()
+        self.write('try:')
+        self.body(node.body)
+        self.newline()
+        self.write('finally:')
+        self.body(node.finalbody)
+
+    def visit_Global(self, node):
+        self.newline()
+        self.write('global ' + ', '.join(node.names))
+
+    def visit_Nonlocal(self, node):
+        self.newline()
+        self.write('nonlocal ' + ', '.join(node.names))
+
+    def visit_Return(self, node):
+        self.newline()
+        self.write('return ')
+        self.visit(node.value)
+
+    def visit_Break(self, node):
+        self.newline()
+        self.write('break')
+
+    def visit_Continue(self, node):
+        self.newline()
+        self.write('continue')
+
+    def visit_Raise(self, node):
+        # XXX: Python 2.6 / 3.0 compatibility
+        self.newline()
+        self.write('raise')
+        if hasattr(node, 'exc') and node.exc is not None:
+            self.write(' ')
+            self.visit(node.exc)
+            if node.cause is not None:
+                self.write(' from ')
+                self.visit(node.cause)
+        elif hasattr(node, 'type') and node.type is not None:
+            self.visit(node.type)
+            if node.inst is not None:
+                self.write(', ')
+                self.visit(node.inst)
+            if node.tback is not None:
+                self.write(', ')
+                self.visit(node.tback)
+
+    # Expressions
+
+    def visit_Attribute(self, node):
+        self.visit(node.value)
+        self.write('.' + node.attr)
+
+    def visit_Call(self, node):
+        want_comma = []
+        def write_comma():
+            if want_comma:
+                self.write(', ')
+            else:
+                want_comma.append(True)
+
+        self.visit(node.func)
+        self.write('(')
+        for arg in node.args:
+            write_comma()
+            self.visit(arg)
+        for keyword in node.keywords:
+            write_comma()
+            self.write(keyword.arg + '=')
+            self.visit(keyword.value)
+        if node.starargs is not None:
+            write_comma()
+            self.write('*')
+            self.visit(node.starargs)
+        if node.kwargs is not None:
+            write_comma()
+            self.write('**')
+            self.visit(node.kwargs)
+        self.write(')')
+
+    def visit_Name(self, node):
+        self.write(node.id)
+
+    def visit_Str(self, node):
+        self.write(repr(node.s))
+
+    def visit_Bytes(self, node):
+        self.write(repr(node.s))
+
+    def visit_Num(self, node):
+        self.write(repr(node.n))
+
+    def visit_Tuple(self, node):
+        self.write('(')
+        idx = -1
+        for idx, item in enumerate(node.elts):
+            if idx:
+                self.write(', ')
+            self.visit(item)
+        self.write(idx and ')' or ',)')
+
+    def sequence_visit(left, right):
+        def visit(self, node):
+            self.write(left)
+            for idx, item in enumerate(node.elts):
+                if idx:
+                    self.write(', ')
+                self.visit(item)
+            self.write(right)
+        return visit
+
+    visit_List = sequence_visit('[', ']')
+    visit_Set = sequence_visit('{', '}')
+    del sequence_visit
+
+    def visit_Dict(self, node):
+        self.write('{')
+        for idx, (key, value) in enumerate(zip(node.keys, node.values)):
+            if idx:
+                self.write(', ')
+            self.visit(key)
+            self.write(': ')
+            self.visit(value)
+        self.write('}')
+
+    def visit_BinOp(self, node):
+        self.write('(')
+        self.visit(node.left)
+        self.write(' %s ' % BINOP_SYMBOLS[type(node.op)])
+        self.visit(node.right)
+        self.write(')')
+
+    def visit_BoolOp(self, node):
+        self.write('(')
+        for idx, value in enumerate(node.values):
+            if idx:
+                self.write(' %s ' % BOOLOP_SYMBOLS[type(node.op)])
+            self.visit(value)
+        self.write(')')
+
+    def visit_Compare(self, node):
+        self.write('(')
+        self.visit(node.left)
+        for op, right in zip(node.ops, node.comparators):
+            self.write(' %s ' % CMPOP_SYMBOLS[type(op)])
+            self.visit(right)
+        self.write(')')
+
+    def visit_UnaryOp(self, node):
+        self.write('(')
+        op = UNARYOP_SYMBOLS[type(node.op)]
+        self.write(op)
+        if op == 'not':
+            self.write(' ')
+        self.visit(node.operand)
+        self.write(')')
+
+    def visit_Subscript(self, node):
+        self.visit(node.value)
+        self.write('[')
+        self.visit(node.slice)
+        self.write(']')
+
+    def visit_Slice(self, node):
+        if node.lower is not None:
+            self.visit(node.lower)
+        self.write(':')
+        if node.upper is not None:
+            self.visit(node.upper)
+        if node.step is not None:
+            self.write(':')
+            if not (isinstance(node.step, Name) and node.step.id == 'None'):
+                self.visit(node.step)
+
+    def visit_ExtSlice(self, node):
+        for idx, item in node.dims:
+            if idx:
+                self.write(', ')
+            self.visit(item)
+
+    def visit_Yield(self, node):
+        self.write('yield ')
+        self.visit(node.value)
+
+    def visit_Lambda(self, node):
+        self.write('lambda ')
+        self.signature(node.args)
+        self.write(': ')
+        self.visit(node.body)
+
+    def visit_Ellipsis(self, node):
+        self.write('Ellipsis')
+
+    def generator_visit(left, right):
+        def visit(self, node):
+            self.write(left)
+            self.visit(node.elt)
+            for comprehension in node.generators:
+                self.visit(comprehension)
+            self.write(right)
+        return visit
+
+    visit_ListComp = generator_visit('[', ']')
+    visit_GeneratorExp = generator_visit('(', ')')
+    visit_SetComp = generator_visit('{', '}')
+    del generator_visit
+
+    def visit_DictComp(self, node):
+        self.write('{')
+        self.visit(node.key)
+        self.write(': ')
+        self.visit(node.value)
+        for comprehension in node.generators:
+            self.visit(comprehension)
+        self.write('}')
+
+    def visit_IfExp(self, node):
+        self.visit(node.body)
+        self.write(' if ')
+        self.visit(node.test)
+        self.write(' else ')
+        self.visit(node.orelse)
+
+    def visit_Starred(self, node):
+        self.write('*')
+        self.visit(node.value)
+
+    def visit_Repr(self, node):
+        # XXX: python 2.6 only
+        self.write('`')
+        self.visit(node.value)
+        self.write('`')
+
+    # Helper Nodes
+
+    def visit_alias(self, node):
+        self.write(node.name)
+        if node.asname is not None:
+            self.write(' as ' + node.asname)
+
+    def visit_comprehension(self, node):
+        self.write(' for ')
+        self.visit(node.target)
+        self.write(' in ')
+        self.visit(node.iter)
+        if node.ifs:
+            for if_ in node.ifs:
+                self.write(' if ')
+                self.visit(if_)
+
+    def visit_excepthandler(self, node):
+        self.newline()
+        self.write('except')
+        if node.type is not None:
+            self.write(' ')
+            self.visit(node.type)
+            if node.name is not None:
+                self.write(' as ')
+                self.visit(node.name)
+        self.write(':')
+        self.body(node.body)
diff --git a/lib3/Mako-0.7.3/mako/ast.py b/lib3/Mako-0.7.3/mako/ast.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/ast.py
@@ -0,0 +1,151 @@
+# mako/ast.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""utilities for analyzing expressions and blocks of Python
+code, as well as generating Python from AST nodes"""
+
+from mako import exceptions, pyparser, util
+import re
+
+class PythonCode(object):
+    """represents information about a string containing Python code"""
+    def __init__(self, code, **exception_kwargs):
+        self.code = code
+
+        # represents all identifiers which are assigned to at some point in
+        # the code
+        self.declared_identifiers = set()
+
+        # represents all identifiers which are referenced before their
+        # assignment, if any
+        self.undeclared_identifiers = set()
+
+        # note that an identifier can be in both the undeclared and declared
+        # lists.
+
+        # using AST to parse instead of using code.co_varnames,
+        # code.co_names has several advantages:
+        # - we can locate an identifier as "undeclared" even if
+        # its declared later in the same block of code
+        # - AST is less likely to break with version changes
+        # (for example, the behavior of co_names changed a little bit
+        # in python version 2.5)
+        if isinstance(code, str):
+            expr = pyparser.parse(code.lstrip(), "exec", **exception_kwargs)
+        else:
+            expr = code
+
+        f = pyparser.FindIdentifiers(self, **exception_kwargs)
+        f.visit(expr)
+
+class ArgumentList(object):
+    """parses a fragment of code as a comma-separated list of expressions"""
+    def __init__(self, code, **exception_kwargs):
+        self.codeargs = []
+        self.args = []
+        self.declared_identifiers = set()
+        self.undeclared_identifiers = set()
+        if isinstance(code, str):
+            if re.match(r"\S", code) and not re.match(r",\s*$", code):
+                # if theres text and no trailing comma, insure its parsed
+                # as a tuple by adding a trailing comma
+                code  += ","
+            expr = pyparser.parse(code, "exec", **exception_kwargs)
+        else:
+            expr = code
+
+        f = pyparser.FindTuple(self, PythonCode, **exception_kwargs)
+        f.visit(expr)
+
+class PythonFragment(PythonCode):
+    """extends PythonCode to provide identifier lookups in partial control
+    statements
+
+    e.g.
+        for x in 5:
+        elif y==9:
+        except (MyException, e):
+    etc.
+    """
+    def __init__(self, code, **exception_kwargs):
+        m = re.match(r'^(\w+)(?:\s+(.*?))?:\s*(#|$)', code.strip(), re.S)
+        if not m:
+            raise exceptions.CompileException(
+                          "Fragment '%s' is not a partial control statement" %
+                          code, **exception_kwargs)
+        if m.group(3):
+            code = code[:m.start(3)]
+        (keyword, expr) = m.group(1,2)
+        if keyword in ['for','if', 'while']:
+            code = code + "pass"
+        elif keyword == 'try':
+            code = code + "pass\nexcept:pass"
+        elif keyword == 'elif' or keyword == 'else':
+            code = "if False:pass\n" + code + "pass"
+        elif keyword == 'except':
+            code = "try:pass\n" + code + "pass"
+        elif keyword == 'with':
+            code = code + "pass"
+        else:
+            raise exceptions.CompileException(
+                                "Unsupported control keyword: '%s'" %
+                                keyword, **exception_kwargs)
+        super(PythonFragment, self).__init__(code, **exception_kwargs)
+
+
+class FunctionDecl(object):
+    """function declaration"""
+    def __init__(self, code, allow_kwargs=True, **exception_kwargs):
+        self.code = code
+        expr = pyparser.parse(code, "exec", **exception_kwargs)
+
+        f = pyparser.ParseFunc(self, **exception_kwargs)
+        f.visit(expr)
+        if not hasattr(self, 'funcname'):
+            raise exceptions.CompileException(
+                              "Code '%s' is not a function declaration" % code,
+                              **exception_kwargs)
+        if not allow_kwargs and self.kwargs:
+            raise exceptions.CompileException(
+                                "'**%s' keyword argument not allowed here" %
+                                self.argnames[-1], **exception_kwargs)
+
+    def get_argument_expressions(self, include_defaults=True):
+        """return the argument declarations of this FunctionDecl as a printable
+        list."""
+
+        namedecls = []
+        defaults = [d for d in self.defaults]
+        kwargs = self.kwargs
+        varargs = self.varargs
+        argnames = [f for f in self.argnames]
+        argnames.reverse()
+        for arg in argnames:
+            default = None
+            if kwargs:
+                arg = "**" + arg
+                kwargs = False
+            elif varargs:
+                arg = "*" + arg
+                varargs = False
+            else:
+                default = len(defaults) and defaults.pop() or None
+            if include_defaults and default:
+                namedecls.insert(0, "%s=%s" %
+                            (arg,
+                            pyparser.ExpressionGenerator(default).value()
+                            )
+                        )
+            else:
+                namedecls.insert(0, arg)
+        return namedecls
+
+class FunctionArgs(FunctionDecl):
+    """the argument portion of a function declaration"""
+
+    def __init__(self, code, **kwargs):
+        super(FunctionArgs, self).__init__("def ANON(%s):pass" % code,
+                **kwargs)
diff --git a/lib3/Mako-0.7.3/mako/cache.py b/lib3/Mako-0.7.3/mako/cache.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/cache.py
@@ -0,0 +1,236 @@
+# mako/cache.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+from mako import exceptions, util
+
+_cache_plugins = util.PluginLoader("mako.cache")
+
+register_plugin = _cache_plugins.register
+register_plugin("beaker", "mako.ext.beaker_cache", "BeakerCacheImpl")
+
+
+class Cache(object):
+    """Represents a data content cache made available to the module
+    space of a specific :class:`.Template` object.
+
+    .. versionadded:: 0.6
+       :class:`.Cache` by itself is mostly a
+       container for a :class:`.CacheImpl` object, which implements
+       a fixed API to provide caching services; specific subclasses exist to
+       implement different
+       caching strategies.   Mako includes a backend that works with
+       the Beaker caching system.   Beaker itself then supports
+       a number of backends (i.e. file, memory, memcached, etc.)
+
+    The construction of a :class:`.Cache` is part of the mechanics
+    of a :class:`.Template`, and programmatic access to this
+    cache is typically via the :attr:`.Template.cache` attribute.
+
+    """
+
+    impl = None
+    """Provide the :class:`.CacheImpl` in use by this :class:`.Cache`.
+
+    This accessor allows a :class:`.CacheImpl` with additional
+    methods beyond that of :class:`.Cache` to be used programmatically.
+
+    """
+
+    id = None
+    """Return the 'id' that identifies this cache.
+
+    This is a value that should be globally unique to the
+    :class:`.Template` associated with this cache, and can
+    be used by a caching system to name a local container
+    for data specific to this template.
+
+    """
+
+    starttime = None
+    """Epochal time value for when the owning :class:`.Template` was
+    first compiled.
+
+    A cache implementation may wish to invalidate data earlier than
+    this timestamp; this has the effect of the cache for a specific
+    :class:`.Template` starting clean any time the :class:`.Template`
+    is recompiled, such as when the original template file changed on
+    the filesystem.
+
+    """
+
+    def __init__(self, template, *args):
+        # check for a stale template calling the
+        # constructor
+        if isinstance(template, str) and args:
+            return
+        self.template = template
+        self.id = template.module.__name__
+        self.starttime = template.module._modified_time
+        self._def_regions = {}
+        self.impl = self._load_impl(self.template.cache_impl)
+
+    def _load_impl(self, name):
+        return _cache_plugins.load(name)(self)
+
+    def get_or_create(self, key, creation_function, **kw):
+        """Retrieve a value from the cache, using the given creation function
+        to generate a new value."""
+
+        return self._ctx_get_or_create(key, creation_function, None, **kw)
+
+    def _ctx_get_or_create(self, key, creation_function, context, **kw):
+        """Retrieve a value from the cache, using the given creation function
+        to generate a new value."""
+
+        if not self.template.cache_enabled:
+            return creation_function()
+
+        return self.impl.get_or_create(key,
+                        creation_function,
+                        **self._get_cache_kw(kw, context))
+
+    def set(self, key, value, **kw):
+        """Place a value in the cache.
+
+        :param key: the value's key.
+        :param value: the value.
+        :param \**kw: cache configuration arguments.
+
+        """
+
+        self.impl.set(key, value, **self._get_cache_kw(kw, None))
+
+    put = set
+    """A synonym for :meth:`.Cache.set`.
+
+    This is here for backwards compatibility.
+
+    """
+
+    def get(self, key, **kw):
+        """Retrieve a value from the cache.
+
+        :param key: the value's key.
+        :param \**kw: cache configuration arguments.  The
+         backend is configured using these arguments upon first request.
+         Subsequent requests that use the same series of configuration
+         values will use that same backend.
+
+        """
+        return self.impl.get(key, **self._get_cache_kw(kw, None))
+
+    def invalidate(self, key, **kw):
+        """Invalidate a value in the cache.
+
+        :param key: the value's key.
+        :param \**kw: cache configuration arguments.  The
+         backend is configured using these arguments upon first request.
+         Subsequent requests that use the same series of configuration
+         values will use that same backend.
+
+        """
+        self.impl.invalidate(key, **self._get_cache_kw(kw, None))
+
+    def invalidate_body(self):
+        """Invalidate the cached content of the "body" method for this
+        template.
+
+        """
+        self.invalidate('render_body', __M_defname='render_body')
+
+    def invalidate_def(self, name):
+        """Invalidate the cached content of a particular ``<%def>`` within this
+        template.
+
+        """
+
+        self.invalidate('render_%s' % name, __M_defname='render_%s' % name)
+
+    def invalidate_closure(self, name):
+        """Invalidate a nested ``<%def>`` within this template.
+
+        Caching of nested defs is a blunt tool as there is no
+        management of scope -- nested defs that use cache tags
+        need to have names unique of all other nested defs in the
+        template, else their content will be overwritten by
+        each other.
+
+        """
+
+        self.invalidate(name, __M_defname=name)
+
+    def _get_cache_kw(self, kw, context):
+        defname = kw.pop('__M_defname', None)
+        if not defname:
+            tmpl_kw = self.template.cache_args.copy()
+            tmpl_kw.update(kw)
+        elif defname in self._def_regions:
+            tmpl_kw = self._def_regions[defname]
+        else:
+            tmpl_kw = self.template.cache_args.copy()
+            tmpl_kw.update(kw)
+            self._def_regions[defname] = tmpl_kw
+        if context and self.impl.pass_context:
+            tmpl_kw = tmpl_kw.copy()
+            tmpl_kw.setdefault('context', context)
+        return tmpl_kw
+
+class CacheImpl(object):
+    """Provide a cache implementation for use by :class:`.Cache`."""
+
+    def __init__(self, cache):
+        self.cache = cache
+
+    pass_context = False
+    """If ``True``, the :class:`.Context` will be passed to
+    :meth:`get_or_create <.CacheImpl.get_or_create>` as the name ``'context'``.
+    """
+
+    def get_or_create(self, key, creation_function, **kw):
+        """Retrieve a value from the cache, using the given creation function
+        to generate a new value.
+
+        This function *must* return a value, either from
+        the cache, or via the given creation function.
+        If the creation function is called, the newly
+        created value should be populated into the cache
+        under the given key before being returned.
+
+        :param key: the value's key.
+        :param creation_function: function that when called generates
+         a new value.
+        :param \**kw: cache configuration arguments.
+
+        """
+        raise NotImplementedError()
+
+    def set(self, key, value, **kw):
+        """Place a value in the cache.
+
+        :param key: the value's key.
+        :param value: the value.
+        :param \**kw: cache configuration arguments.
+
+        """
+        raise NotImplementedError()
+
+    def get(self, key, **kw):
+        """Retrieve a value from the cache.
+
+        :param key: the value's key.
+        :param \**kw: cache configuration arguments.
+
+        """
+        raise NotImplementedError()
+
+    def invalidate(self, key, **kw):
+        """Invalidate a value in the cache.
+
+        :param key: the value's key.
+        :param \**kw: cache configuration arguments.
+
+        """
+        raise NotImplementedError()
diff --git a/lib3/Mako-0.7.3/mako/codegen.py b/lib3/Mako-0.7.3/mako/codegen.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/codegen.py
@@ -0,0 +1,1215 @@
+# mako/codegen.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""provides functionality for rendering a parsetree constructing into module
+source code."""
+
+import time
+import re
+from mako.pygen import PythonPrinter
+from mako import util, ast, parsetree, filters, exceptions
+
+MAGIC_NUMBER = 8
+
+# names which are hardwired into the
+# template and are not accessed via the
+# context itself
+RESERVED_NAMES = set(['context', 'loop', 'UNDEFINED'])
+
+def compile(node,
+                uri,
+                filename=None,
+                default_filters=None,
+                buffer_filters=None,
+                imports=None,
+                source_encoding=None,
+                generate_magic_comment=True,
+                disable_unicode=False,
+                strict_undefined=False,
+                enable_loop=True,
+                reserved_names=()):
+
+    """Generate module source code given a parsetree node,
+      uri, and optional source filename"""
+
+    # if on Py2K, push the "source_encoding" string to be
+    # a bytestring itself, as we will be embedding it into
+    # the generated source and we don't want to coerce the
+    # result into a unicode object, in "disable_unicode" mode
+    if not util.py3k and isinstance(source_encoding, str):
+        source_encoding = source_encoding.encode(source_encoding)
+
+
+    buf = util.FastEncodingBuffer()
+
+    printer = PythonPrinter(buf)
+    _GenerateRenderMethod(printer,
+                            _CompileContext(uri,
+                                            filename,
+                                            default_filters,
+                                            buffer_filters,
+                                            imports,
+                                            source_encoding,
+                                            generate_magic_comment,
+                                            disable_unicode,
+                                            strict_undefined,
+                                            enable_loop,
+                                            reserved_names),
+                                node)
+    return buf.getvalue()
+
+class _CompileContext(object):
+    def __init__(self,
+                    uri,
+                    filename,
+                    default_filters,
+                    buffer_filters,
+                    imports,
+                    source_encoding,
+                    generate_magic_comment,
+                    disable_unicode,
+                    strict_undefined,
+                    enable_loop,
+                    reserved_names):
+        self.uri = uri
+        self.filename = filename
+        self.default_filters = default_filters
+        self.buffer_filters = buffer_filters
+        self.imports = imports
+        self.source_encoding = source_encoding
+        self.generate_magic_comment = generate_magic_comment
+        self.disable_unicode = disable_unicode
+        self.strict_undefined = strict_undefined
+        self.enable_loop = enable_loop
+        self.reserved_names = reserved_names
+
+class _GenerateRenderMethod(object):
+    """A template visitor object which generates the
+       full module source for a template.
+
+    """
+    def __init__(self, printer, compiler, node):
+        self.printer = printer
+        self.last_source_line = -1
+        self.compiler = compiler
+        self.node = node
+        self.identifier_stack = [None]
+
+        self.in_def = isinstance(node, (parsetree.DefTag, parsetree.BlockTag))
+
+        if self.in_def:
+            name = "render_%s" % node.funcname
+            args = node.get_argument_expressions()
+            filtered = len(node.filter_args.args) > 0
+            buffered = eval(node.attributes.get('buffered', 'False'))
+            cached = eval(node.attributes.get('cached', 'False'))
+            defs = None
+            pagetag = None
+            if node.is_block and not node.is_anonymous:
+                args += ['**pageargs']
+        else:
+            defs = self.write_toplevel()
+            pagetag = self.compiler.pagetag
+            name = "render_body"
+            if pagetag is not None:
+                args = pagetag.body_decl.get_argument_expressions()
+                if not pagetag.body_decl.kwargs:
+                    args += ['**pageargs']
+                cached = eval(pagetag.attributes.get('cached', 'False'))
+                self.compiler.enable_loop = self.compiler.enable_loop or eval(
+                                        pagetag.attributes.get(
+                                                'enable_loop', 'False')
+                                    )
+            else:
+                args = ['**pageargs']
+                cached = False
+            buffered = filtered = False
+        if args is None:
+            args = ['context']
+        else:
+            args = [a for a in ['context'] + args]
+
+        self.write_render_callable(
+                            pagetag or node,
+                            name, args,
+                            buffered, filtered, cached)
+
+        if defs is not None:
+            for node in defs:
+                _GenerateRenderMethod(printer, compiler, node)
+
+    @property
+    def identifiers(self):
+        return self.identifier_stack[-1]
+
+    def write_toplevel(self):
+        """Traverse a template structure for module-level directives and
+        generate the start of module-level code.
+
+        """
+        inherit = []
+        namespaces = {}
+        module_code = []
+        encoding = [None]
+
+        self.compiler.pagetag = None
+
+        class FindTopLevel(object):
+            def visitInheritTag(s, node):
+                inherit.append(node)
+            def visitNamespaceTag(s, node):
+                namespaces[node.name] = node
+            def visitPageTag(s, node):
+                self.compiler.pagetag = node
+            def visitCode(s, node):
+                if node.ismodule:
+                    module_code.append(node)
+
+        f = FindTopLevel()
+        for n in self.node.nodes:
+            n.accept_visitor(f)
+
+        self.compiler.namespaces = namespaces
+
+        module_ident = set()
+        for n in module_code:
+            module_ident = module_ident.union(n.declared_identifiers())
+
+        module_identifiers = _Identifiers(self.compiler)
+        module_identifiers.declared = module_ident
+
+        # module-level names, python code
+        if self.compiler.generate_magic_comment and \
+            self.compiler.source_encoding:
+            self.printer.writeline("# -*- encoding:%s -*-" %
+                                    self.compiler.source_encoding)
+
+        self.printer.writeline("from mako import runtime, filters, cache")
+        self.printer.writeline("UNDEFINED = runtime.UNDEFINED")
+        self.printer.writeline("__M_dict_builtin = dict")
+        self.printer.writeline("__M_locals_builtin = locals")
+        self.printer.writeline("_magic_number = %r" % MAGIC_NUMBER)
+        self.printer.writeline("_modified_time = %r" % time.time())
+        self.printer.writeline("_enable_loop = %r" % self.compiler.enable_loop)
+        self.printer.writeline(
+                            "_template_filename = %r" % self.compiler.filename)
+        self.printer.writeline("_template_uri = %r" % self.compiler.uri)
+        self.printer.writeline(
+                    "_source_encoding = %r" % self.compiler.source_encoding)
+        if self.compiler.imports:
+            buf = ''
+            for imp in self.compiler.imports:
+                buf += imp + "\n"
+                self.printer.writeline(imp)
+            impcode = ast.PythonCode(
+                            buf,
+                            source='', lineno=0,
+                            pos=0,
+                            filename='template defined imports')
+        else:
+            impcode = None
+
+        main_identifiers = module_identifiers.branch(self.node)
+        module_identifiers.topleveldefs = \
+            module_identifiers.topleveldefs.\
+                union(main_identifiers.topleveldefs)
+        module_identifiers.declared.add("UNDEFINED")
+        if impcode:
+            module_identifiers.declared.update(impcode.declared_identifiers)
+
+        self.compiler.identifiers = module_identifiers
+        self.printer.writeline("_exports = %r" %
+                            [n.name for n in
+                            list(main_identifiers.topleveldefs.values())]
+                        )
+        self.printer.write("\n\n")
+
+        if len(module_code):
+            self.write_module_code(module_code)
+
+        if len(inherit):
+            self.write_namespaces(namespaces)
+            self.write_inherit(inherit[-1])
+        elif len(namespaces):
+            self.write_namespaces(namespaces)
+
+        return list(main_identifiers.topleveldefs.values())
+
+    def write_render_callable(self, node, name, args, buffered, filtered,
+            cached):
+        """write a top-level render callable.
+
+        this could be the main render() method or that of a top-level def."""
+
+        if self.in_def:
+            decorator = node.decorator
+            if decorator:
+                self.printer.writeline(
+                                 "@runtime._decorate_toplevel(%s)" % decorator)
+
+        self.printer.writelines(
+            "def %s(%s):" % (name, ','.join(args)),
+                # push new frame, assign current frame to __M_caller
+                "__M_caller = context.caller_stack._push_frame()",
+                "try:"
+        )
+        if buffered or filtered or cached:
+            self.printer.writeline("context._push_buffer()")
+
+        self.identifier_stack.append(
+                                   self.compiler.identifiers.branch(self.node))
+        if (not self.in_def or self.node.is_block) and '**pageargs' in args:
+            self.identifier_stack[-1].argument_declared.add('pageargs')
+
+        if not self.in_def and (
+                                len(self.identifiers.locally_assigned) > 0 or
+                                len(self.identifiers.argument_declared) > 0
+                                ):
+            self.printer.writeline("__M_locals = __M_dict_builtin(%s)" %
+                                    ','.join([
+                                            "%s=%s" % (x, x) for x in
+                                            self.identifiers.argument_declared
+                                            ]))
+
+        self.write_variable_declares(self.identifiers, toplevel=True)
+
+        for n in self.node.nodes:
+            n.accept_visitor(self)
+
+        self.write_def_finish(self.node, buffered, filtered, cached)
+        self.printer.writeline(None)
+        self.printer.write("\n\n")
+        if cached:
+            self.write_cache_decorator(
+                                node, name,
+                                args, buffered,
+                                self.identifiers, toplevel=True)
+
+    def write_module_code(self, module_code):
+        """write module-level template code, i.e. that which
+        is enclosed in <%! %> tags in the template."""
+        for n in module_code:
+            self.write_source_comment(n)
+            self.printer.write_indented_block(n.text)
+
+    def write_inherit(self, node):
+        """write the module-level inheritance-determination callable."""
+
+        self.printer.writelines(
+            "def _mako_inherit(template, context):",
+                "_mako_generate_namespaces(context)",
+                "return runtime._inherit_from(context, %s, _template_uri)" %
+                 (node.parsed_attributes['file']),
+                None
+            )
+
+    def write_namespaces(self, namespaces):
+        """write the module-level namespace-generating callable."""
+        self.printer.writelines(
+            "def _mako_get_namespace(context, name):",
+                "try:",
+                    "return context.namespaces[(__name__, name)]",
+                "except KeyError:",
+                    "_mako_generate_namespaces(context)",
+                "return context.namespaces[(__name__, name)]",
+            None, None
+            )
+        self.printer.writeline("def _mako_generate_namespaces(context):")
+
+
+        for node in list(namespaces.values()):
+            if 'import' in node.attributes:
+                self.compiler.has_ns_imports = True
+            self.write_source_comment(node)
+            if len(node.nodes):
+                self.printer.writeline("def make_namespace():")
+                export = []
+                identifiers = self.compiler.identifiers.branch(node)
+                self.in_def = True
+                class NSDefVisitor(object):
+                    def visitDefTag(s, node):
+                        s.visitDefOrBase(node)
+
+                    def visitBlockTag(s, node):
+                        s.visitDefOrBase(node)
+
+                    def visitDefOrBase(s, node):
+                        if node.is_anonymous:
+                            raise exceptions.CompileException(
+                                "Can't put anonymous blocks inside "
+                                "<%namespace>",
+                                **node.exception_kwargs
+                            )
+                        self.write_inline_def(node, identifiers, nested=False)
+                        export.append(node.funcname)
+                vis = NSDefVisitor()
+                for n in node.nodes:
+                    n.accept_visitor(vis)
+                self.printer.writeline("return [%s]" % (','.join(export)))
+                self.printer.writeline(None)
+                self.in_def = False
+                callable_name = "make_namespace()"
+            else:
+                callable_name = "None"
+
+            if 'file' in node.parsed_attributes:
+                self.printer.writeline(
+                                "ns = runtime.TemplateNamespace(%r,"
+                                " context._clean_inheritance_tokens(),"
+                                " templateuri=%s, callables=%s, "
+                                " calling_uri=_template_uri)" %
+                                (
+                                   node.name,
+                                   node.parsed_attributes.get('file', 'None'),
+                                   callable_name,
+                                )
+                            )
+            elif 'module' in node.parsed_attributes:
+                self.printer.writeline(
+                                "ns = runtime.ModuleNamespace(%r,"
+                                " context._clean_inheritance_tokens(),"
+                                " callables=%s, calling_uri=_template_uri,"
+                                " module=%s)" %
+                                (
+                                   node.name,
+                                   callable_name,
+                                   node.parsed_attributes.get('module', 'None')
+                                )
+                            )
+            else:
+                self.printer.writeline(
+                                "ns = runtime.Namespace(%r,"
+                                " context._clean_inheritance_tokens(),"
+                                " callables=%s, calling_uri=_template_uri)" %
+                                (
+                                    node.name,
+                                    callable_name,
+                                )
+                            )
+            if eval(node.attributes.get('inheritable', "False")):
+                self.printer.writeline("context['self'].%s = ns" % (node.name))
+
+            self.printer.writeline(
+                   "context.namespaces[(__name__, %s)] = ns" % repr(node.name))
+            self.printer.write("\n")
+        if not len(namespaces):
+            self.printer.writeline("pass")
+        self.printer.writeline(None)
+
+    def write_variable_declares(self, identifiers, toplevel=False, limit=None):
+        """write variable declarations at the top of a function.
+
+        the variable declarations are in the form of callable
+        definitions for defs and/or name lookup within the
+        function's context argument. the names declared are based
+        on the names that are referenced in the function body,
+        which don't otherwise have any explicit assignment
+        operation. names that are assigned within the body are
+        assumed to be locally-scoped variables and are not
+        separately declared.
+
+        for def callable definitions, if the def is a top-level
+        callable then a 'stub' callable is generated which wraps
+        the current Context into a closure. if the def is not
+        top-level, it is fully rendered as a local closure.
+
+        """
+
+        # collection of all defs available to us in this scope
+        comp_idents = dict([(c.funcname, c) for c in identifiers.defs])
+        to_write = set()
+
+        # write "context.get()" for all variables we are going to
+        # need that arent in the namespace yet
+        to_write = to_write.union(identifiers.undeclared)
+
+        # write closure functions for closures that we define
+        # right here
+        to_write = to_write.union(
+                        [c.funcname for c in list(identifiers.closuredefs.values())])
+
+        # remove identifiers that are declared in the argument
+        # signature of the callable
+        to_write = to_write.difference(identifiers.argument_declared)
+
+        # remove identifiers that we are going to assign to.
+        # in this way we mimic Python's behavior,
+        # i.e. assignment to a variable within a block
+        # means that variable is now a "locally declared" var,
+        # which cannot be referenced beforehand.
+        to_write = to_write.difference(identifiers.locally_declared)
+
+        if self.compiler.enable_loop:
+            has_loop = "loop" in to_write
+            to_write.discard("loop")
+        else:
+            has_loop = False
+
+        # if a limiting set was sent, constraint to those items in that list
+        # (this is used for the caching decorator)
+        if limit is not None:
+            to_write = to_write.intersection(limit)
+
+        if toplevel and getattr(self.compiler, 'has_ns_imports', False):
+            self.printer.writeline("_import_ns = {}")
+            self.compiler.has_imports = True
+            for ident, ns in self.compiler.namespaces.items():
+                if 'import' in ns.attributes:
+                    self.printer.writeline(
+                            "_mako_get_namespace(context, %r)."\
+                                    "_populate(_import_ns, %r)" %
+                            (
+                                ident,
+                                re.split(r'\s*,\s*', ns.attributes['import'])
+                            ))
+
+        if has_loop:
+            self.printer.writeline(
+                'loop = __M_loop = runtime.LoopStack()'
+            )
+
+        for ident in to_write:
+            if ident in comp_idents:
+                comp = comp_idents[ident]
+                if comp.is_block:
+                    if not comp.is_anonymous:
+                        self.write_def_decl(comp, identifiers)
+                    else:
+                        self.write_inline_def(comp, identifiers, nested=True)
+                else:
+                    if comp.is_root():
+                        self.write_def_decl(comp, identifiers)
+                    else:
+                        self.write_inline_def(comp, identifiers, nested=True)
+
+            elif ident in self.compiler.namespaces:
+                self.printer.writeline(
+                            "%s = _mako_get_namespace(context, %r)" %
+                                (ident, ident)
+                            )
+            else:
+                if getattr(self.compiler, 'has_ns_imports', False):
+                    if self.compiler.strict_undefined:
+                        self.printer.writelines(
+                        "%s = _import_ns.get(%r, UNDEFINED)" %
+                        (ident, ident),
+                        "if %s is UNDEFINED:" % ident,
+                            "try:",
+                                "%s = context[%r]" % (ident, ident),
+                            "except KeyError:",
+                                "raise NameError(\"'%s' is not defined\")" %
+                                    ident,
+                            None, None
+                        )
+                    else:
+                        self.printer.writeline(
+                        "%s = _import_ns.get(%r, context.get(%r, UNDEFINED))" %
+                        (ident, ident, ident))
+                else:
+                    if self.compiler.strict_undefined:
+                        self.printer.writelines(
+                            "try:",
+                                "%s = context[%r]" % (ident, ident),
+                            "except KeyError:",
+                                "raise NameError(\"'%s' is not defined\")" %
+                                    ident,
+                            None
+                        )
+                    else:
+                        self.printer.writeline(
+                            "%s = context.get(%r, UNDEFINED)" % (ident, ident)
+                        )
+
+        self.printer.writeline("__M_writer = context.writer()")
+
+    def write_source_comment(self, node):
+        """write a source comment containing the line number of the
+        corresponding template line."""
+        if self.last_source_line != node.lineno:
+            self.printer.writeline("# SOURCE LINE %d" % node.lineno)
+            self.last_source_line = node.lineno
+
+    def write_def_decl(self, node, identifiers):
+        """write a locally-available callable referencing a top-level def"""
+        funcname = node.funcname
+        namedecls = node.get_argument_expressions()
+        nameargs = node.get_argument_expressions(include_defaults=False)
+
+        if not self.in_def and (
+                                len(self.identifiers.locally_assigned) > 0 or
+                                len(self.identifiers.argument_declared) > 0):
+            nameargs.insert(0, 'context.locals_(__M_locals)')
+        else:
+            nameargs.insert(0, 'context')
+        self.printer.writeline("def %s(%s):" % (funcname, ",".join(namedecls)))
+        self.printer.writeline(
+                       "return render_%s(%s)" % (funcname, ",".join(nameargs)))
+        self.printer.writeline(None)
+
+    def write_inline_def(self, node, identifiers, nested):
+        """write a locally-available def callable inside an enclosing def."""
+
+        namedecls = node.get_argument_expressions()
+
+        decorator = node.decorator
+        if decorator:
+            self.printer.writeline(
+                          "@runtime._decorate_inline(context, %s)" % decorator)
+        self.printer.writeline(
+                          "def %s(%s):" % (node.funcname, ",".join(namedecls)))
+        filtered = len(node.filter_args.args) > 0
+        buffered = eval(node.attributes.get('buffered', 'False'))
+        cached = eval(node.attributes.get('cached', 'False'))
+        self.printer.writelines(
+            # push new frame, assign current frame to __M_caller
+            "__M_caller = context.caller_stack._push_frame()",
+            "try:"
+            )
+        if buffered or filtered or cached:
+            self.printer.writelines(
+                "context._push_buffer()",
+                )
+
+        identifiers = identifiers.branch(node, nested=nested)
+
+        self.write_variable_declares(identifiers)
+
+        self.identifier_stack.append(identifiers)
+        for n in node.nodes:
+            n.accept_visitor(self)
+        self.identifier_stack.pop()
+
+        self.write_def_finish(node, buffered, filtered, cached)
+        self.printer.writeline(None)
+        if cached:
+            self.write_cache_decorator(node, node.funcname,
+                                        namedecls, False, identifiers,
+                                        inline=True, toplevel=False)
+
+    def write_def_finish(self, node, buffered, filtered, cached,
+            callstack=True):
+        """write the end section of a rendering function, either outermost or
+        inline.
+
+        this takes into account if the rendering function was filtered,
+        buffered, etc.  and closes the corresponding try: block if any, and
+        writes code to retrieve captured content, apply filters, send proper
+        return value."""
+
+        if not buffered and not cached and not filtered:
+            self.printer.writeline("return ''")
+            if callstack:
+                self.printer.writelines(
+                    "finally:",
+                        "context.caller_stack._pop_frame()",
+                    None
+                )
+
+        if buffered or filtered or cached:
+            if buffered or cached:
+                # in a caching scenario, don't try to get a writer
+                # from the context after popping; assume the caching
+                # implemenation might be using a context with no
+                # extra buffers
+                self.printer.writelines(
+                    "finally:",
+                        "__M_buf = context._pop_buffer()"
+                )
+            else:
+                self.printer.writelines(
+                   "finally:",
+                       "__M_buf, __M_writer = context._pop_buffer_and_writer()"
+                )
+
+            if callstack:
+                self.printer.writeline("context.caller_stack._pop_frame()")
+
+            s = "__M_buf.getvalue()"
+            if filtered:
+                s = self.create_filter_callable(node.filter_args.args, s,
+                                                False)
+            self.printer.writeline(None)
+            if buffered and not cached:
+                s = self.create_filter_callable(self.compiler.buffer_filters,
+                                                s, False)
+            if buffered or cached:
+                self.printer.writeline("return %s" % s)
+            else:
+                self.printer.writelines(
+                    "__M_writer(%s)" % s,
+                    "return ''"
+                )
+
+    def write_cache_decorator(self, node_or_pagetag, name,
+                                    args, buffered, identifiers,
+                                    inline=False, toplevel=False):
+        """write a post-function decorator to replace a rendering
+            callable with a cached version of itself."""
+
+        self.printer.writeline("__M_%s = %s" % (name, name))
+        cachekey = node_or_pagetag.parsed_attributes.get('cache_key',
+                                                         repr(name))
+
+        cache_args = {}
+        if self.compiler.pagetag is not None:
+            cache_args.update(
+                (
+                    pa[6:],
+                    self.compiler.pagetag.parsed_attributes[pa]
+                )
+                for pa in self.compiler.pagetag.parsed_attributes
+                if pa.startswith('cache_') and pa != 'cache_key'
+            )
+        cache_args.update(
+            (
+                pa[6:],
+                node_or_pagetag.parsed_attributes[pa]
+            ) for pa in node_or_pagetag.parsed_attributes
+            if pa.startswith('cache_') and pa != 'cache_key'
+        )
+        if 'timeout' in cache_args:
+            cache_args['timeout'] = int(eval(cache_args['timeout']))
+
+        self.printer.writeline("def %s(%s):" % (name, ','.join(args)))
+
+        # form "arg1, arg2, arg3=arg3, arg4=arg4", etc.
+        pass_args = [
+                        '=' in a and "%s=%s" % ((a.split('=')[0],)*2) or a
+                        for a in args
+                    ]
+
+        self.write_variable_declares(
+                            identifiers,
+                            toplevel=toplevel,
+                            limit=node_or_pagetag.undeclared_identifiers()
+                        )
+        if buffered:
+            s = "context.get('local')."\
+                "cache._ctx_get_or_create("\
+                "%s, lambda:__M_%s(%s),  context, %s__M_defname=%r)" % \
+                            (cachekey, name, ','.join(pass_args),
+                            ''.join(["%s=%s, " % (k,v)
+                            for k, v in list(cache_args.items())]),
+                            name
+                            )
+            # apply buffer_filters
+            s = self.create_filter_callable(self.compiler.buffer_filters, s,
+                                            False)
+            self.printer.writelines("return " + s,None)
+        else:
+            self.printer.writelines(
+                    "__M_writer(context.get('local')."
+                    "cache._ctx_get_or_create("\
+                    "%s, lambda:__M_%s(%s), context, %s__M_defname=%r))" %
+                    (cachekey, name, ','.join(pass_args),
+                    ''.join(["%s=%s, " % (k,v)
+                        for k, v in list(cache_args.items())]),
+                    name,
+                    ),
+                    "return ''",
+                None
+            )
+
+    def create_filter_callable(self, args, target, is_expression):
+        """write a filter-applying expression based on the filters
+        present in the given filter names, adjusting for the global
+        'default' filter aliases as needed."""
+
+        def locate_encode(name):
+            if re.match(r'decode\..+', name):
+                return "filters." + name
+            elif self.compiler.disable_unicode:
+                return filters.NON_UNICODE_ESCAPES.get(name, name)
+            else:
+                return filters.DEFAULT_ESCAPES.get(name, name)
+
+        if 'n' not in args:
+            if is_expression:
+                if self.compiler.pagetag:
+                    args = self.compiler.pagetag.filter_args.args + args
+                if self.compiler.default_filters:
+                    args = self.compiler.default_filters + args
+        for e in args:
+            # if filter given as a function, get just the identifier portion
+            if e == 'n':
+                continue
+            m = re.match(r'(.+?)(\(.*\))', e)
+            if m:
+                (ident, fargs) = m.group(1,2)
+                f = locate_encode(ident)
+                e = f + fargs
+            else:
+                x = e
+                e = locate_encode(e)
+                assert e is not None
+            target = "%s(%s)" % (e, target)
+        return target
+
+    def visitExpression(self, node):
+        self.write_source_comment(node)
+        if len(node.escapes) or \
+                (
+                    self.compiler.pagetag is not None and
+                    len(self.compiler.pagetag.filter_args.args)
+                ) or \
+                len(self.compiler.default_filters):
+
+            s = self.create_filter_callable(node.escapes_code.args,
+                                            "%s" % node.text, True)
+            self.printer.writeline("__M_writer(%s)" % s)
+        else:
+            self.printer.writeline("__M_writer(%s)" % node.text)
+
+    def visitControlLine(self, node):
+        if node.isend:
+            self.printer.writeline(None)
+            if node.has_loop_context:
+                self.printer.writeline('finally:')
+                self.printer.writeline("loop = __M_loop._exit()")
+                self.printer.writeline(None)
+        else:
+            self.write_source_comment(node)
+            if self.compiler.enable_loop and node.keyword == 'for':
+                text = mangle_mako_loop(node, self.printer)
+            else:
+                text = node.text
+            self.printer.writeline(text)
+            children = node.get_children()
+            # this covers the three situations where we want to insert a pass:
+            #    1) a ternary control line with no children,
+            #    2) a primary control line with nothing but its own ternary
+            #          and end control lines, and
+            #    3) any control line with no content other than comments
+            if not children or (
+                    util.all(isinstance(c, (parsetree.Comment,
+                                            parsetree.ControlLine))
+                             for c in children) and
+                    util.all((node.is_ternary(c.keyword) or c.isend)
+                             for c in children
+                             if isinstance(c, parsetree.ControlLine))):
+                self.printer.writeline("pass")
+
+    def visitText(self, node):
+        self.write_source_comment(node)
+        self.printer.writeline("__M_writer(%s)" % repr(node.content))
+
+    def visitTextTag(self, node):
+        filtered = len(node.filter_args.args) > 0
+        if filtered:
+            self.printer.writelines(
+                "__M_writer = context._push_writer()",
+                "try:",
+            )
+        for n in node.nodes:
+            n.accept_visitor(self)
+        if filtered:
+            self.printer.writelines(
+                "finally:",
+                "__M_buf, __M_writer = context._pop_buffer_and_writer()",
+                "__M_writer(%s)" %
+                self.create_filter_callable(
+                                node.filter_args.args,
+                                "__M_buf.getvalue()",
+                                False),
+                None
+                )
+
+    def visitCode(self, node):
+        if not node.ismodule:
+            self.write_source_comment(node)
+            self.printer.write_indented_block(node.text)
+
+            if not self.in_def and len(self.identifiers.locally_assigned) > 0:
+                # if we are the "template" def, fudge locally
+                # declared/modified variables into the "__M_locals" dictionary,
+                # which is used for def calls within the same template,
+                # to simulate "enclosing scope"
+                self.printer.writeline(
+                      '__M_locals_builtin_stored = __M_locals_builtin()')
+                self.printer.writeline(
+                      '__M_locals.update(__M_dict_builtin([(__M_key,'
+                      ' __M_locals_builtin_stored[__M_key]) for __M_key in'
+                      ' [%s] if __M_key in __M_locals_builtin_stored]))' %
+                      ','.join([repr(x) for x in node.declared_identifiers()]))
+
+    def visitIncludeTag(self, node):
+        self.write_source_comment(node)
+        args = node.attributes.get('args')
+        if args:
+            self.printer.writeline(
+                      "runtime._include_file(context, %s, _template_uri, %s)" %
+                      (node.parsed_attributes['file'], args))
+        else:
+            self.printer.writeline(
+                        "runtime._include_file(context, %s, _template_uri)" %
+                        (node.parsed_attributes['file']))
+
+    def visitNamespaceTag(self, node):
+        pass
+
+    def visitDefTag(self, node):
+        pass
+
+    def visitBlockTag(self, node):
+        if node.is_anonymous:
+            self.printer.writeline("%s()" % node.funcname)
+        else:
+            nameargs = node.get_argument_expressions(include_defaults=False)
+            nameargs += ['**pageargs']
+            self.printer.writeline("if 'parent' not in context._data or "
+                                  "not hasattr(context._data['parent'], '%s'):"
+                                  % node.funcname)
+            self.printer.writeline(
+                "context['self'].%s(%s)" % (node.funcname, ",".join(nameargs)))
+            self.printer.writeline("\n")
+
+    def visitCallNamespaceTag(self, node):
+        # TODO: we can put namespace-specific checks here, such
+        # as ensure the given namespace will be imported,
+        # pre-import the namespace, etc.
+        self.visitCallTag(node)
+
+    def visitCallTag(self, node):
+        self.printer.writeline("def ccall(caller):")
+        export = ['body']
+        callable_identifiers = self.identifiers.branch(node, nested=True)
+        body_identifiers = callable_identifiers.branch(node, nested=False)
+        # we want the 'caller' passed to ccall to be used
+        # for the body() function, but for other non-body()
+        # <%def>s within <%call> we want the current caller
+        # off the call stack (if any)
+        body_identifiers.add_declared('caller')
+
+        self.identifier_stack.append(body_identifiers)
+        class DefVisitor(object):
+            def visitDefTag(s, node):
+                s.visitDefOrBase(node)
+
+            def visitBlockTag(s, node):
+                s.visitDefOrBase(node)
+
+            def visitDefOrBase(s, node):
+                self.write_inline_def(node, callable_identifiers, nested=False)
+                if not node.is_anonymous:
+                    export.append(node.funcname)
+                # remove defs that are within the <%call> from the
+                # "closuredefs" defined in the body, so they dont render twice
+                if node.funcname in body_identifiers.closuredefs:
+                    del body_identifiers.closuredefs[node.funcname]
+
+        vis = DefVisitor()
+        for n in node.nodes:
+            n.accept_visitor(vis)
+        self.identifier_stack.pop()
+
+        bodyargs = node.body_decl.get_argument_expressions()
+        self.printer.writeline("def body(%s):" % ','.join(bodyargs))
+
+        # TODO: figure out best way to specify
+        # buffering/nonbuffering (at call time would be better)
+        buffered = False
+        if buffered:
+            self.printer.writelines(
+                "context._push_buffer()",
+                "try:"
+            )
+        self.write_variable_declares(body_identifiers)
+        self.identifier_stack.append(body_identifiers)
+
+        for n in node.nodes:
+            n.accept_visitor(self)
+        self.identifier_stack.pop()
+
+        self.write_def_finish(node, buffered, False, False, callstack=False)
+        self.printer.writelines(
+            None,
+            "return [%s]" % (','.join(export)),
+            None
+        )
+
+        self.printer.writelines(
+            # push on caller for nested call
+            "context.caller_stack.nextcaller = "
+                "runtime.Namespace('caller', context, "
+                                  "callables=ccall(__M_caller))",
+            "try:")
+        self.write_source_comment(node)
+        self.printer.writelines(
+                "__M_writer(%s)" % self.create_filter_callable(
+                                                    [], node.expression, True),
+            "finally:",
+                "context.caller_stack.nextcaller = None",
+            None
+        )
+
+class _Identifiers(object):
+    """tracks the status of identifier names as template code is rendered."""
+
+    def __init__(self, compiler, node=None, parent=None, nested=False):
+        if parent is not None:
+            # if we are the branch created in write_namespaces(),
+            # we don't share any context from the main body().
+            if isinstance(node, parsetree.NamespaceTag):
+                self.declared = set()
+                self.topleveldefs = util.SetLikeDict()
+            else:
+                # things that have already been declared
+                # in an enclosing namespace (i.e. names we can just use)
+                self.declared = set(parent.declared).\
+                         union([c.name for c in list(parent.closuredefs.values())]).\
+                         union(parent.locally_declared).\
+                         union(parent.argument_declared)
+
+                # if these identifiers correspond to a "nested"
+                # scope, it means whatever the parent identifiers
+                # had as undeclared will have been declared by that parent,
+                # and therefore we have them in our scope.
+                if nested:
+                    self.declared = self.declared.union(parent.undeclared)
+
+                # top level defs that are available
+                self.topleveldefs = util.SetLikeDict(**parent.topleveldefs)
+        else:
+            self.declared = set()
+            self.topleveldefs = util.SetLikeDict()
+
+        self.compiler = compiler
+
+        # things within this level that are referenced before they
+        # are declared (e.g. assigned to)
+        self.undeclared = set()
+
+        # things that are declared locally.  some of these things
+        # could be in the "undeclared" list as well if they are
+        # referenced before declared
+        self.locally_declared = set()
+
+        # assignments made in explicit python blocks.
+        # these will be propagated to
+        # the context of local def calls.
+        self.locally_assigned = set()
+
+        # things that are declared in the argument
+        # signature of the def callable
+        self.argument_declared = set()
+
+        # closure defs that are defined in this level
+        self.closuredefs = util.SetLikeDict()
+
+        self.node = node
+
+        if node is not None:
+            node.accept_visitor(self)
+
+        illegal_names = self.compiler.reserved_names.intersection(
+                                                         self.locally_declared)
+        if illegal_names:
+            raise exceptions.NameConflictError(
+                "Reserved words declared in template: %s" %
+                ", ".join(illegal_names))
+
+
+    def branch(self, node, **kwargs):
+        """create a new Identifiers for a new Node, with
+          this Identifiers as the parent."""
+
+        return _Identifiers(self.compiler, node, self, **kwargs)
+
+    @property
+    def defs(self):
+        return set(self.topleveldefs.union(self.closuredefs).values())
+
+    def __repr__(self):
+        return "Identifiers(declared=%r, locally_declared=%r, "\
+                "undeclared=%r, topleveldefs=%r, closuredefs=%r, "\
+                "argumentdeclared=%r)" %\
+                (
+                    list(self.declared),
+                    list(self.locally_declared),
+                    list(self.undeclared),
+                    [c.name for c in list(self.topleveldefs.values())],
+                    [c.name for c in list(self.closuredefs.values())],
+                    self.argument_declared)
+
+    def check_declared(self, node):
+        """update the state of this Identifiers with the undeclared
+            and declared identifiers of the given node."""
+
+        for ident in node.undeclared_identifiers():
+            if ident != 'context' and\
+                       ident not in self.declared.union(self.locally_declared):
+                self.undeclared.add(ident)
+        for ident in node.declared_identifiers():
+            self.locally_declared.add(ident)
+
+    def add_declared(self, ident):
+        self.declared.add(ident)
+        if ident in self.undeclared:
+            self.undeclared.remove(ident)
+
+    def visitExpression(self, node):
+        self.check_declared(node)
+
+    def visitControlLine(self, node):
+        self.check_declared(node)
+
+    def visitCode(self, node):
+        if not node.ismodule:
+            self.check_declared(node)
+            self.locally_assigned = self.locally_assigned.union(
+                                                   node.declared_identifiers())
+
+    def visitNamespaceTag(self, node):
+        # only traverse into the sub-elements of a
+        # <%namespace> tag if we are the branch created in
+        # write_namespaces()
+        if self.node is node:
+            for n in node.nodes:
+                n.accept_visitor(self)
+
+    def _check_name_exists(self, collection, node):
+        existing = collection.get(node.funcname)
+        collection[node.funcname] = node
+        if existing is not None and \
+            existing is not node and \
+            (node.is_block or existing.is_block):
+            raise exceptions.CompileException(
+                    "%%def or %%block named '%s' already "
+                    "exists in this template." %
+                    node.funcname, **node.exception_kwargs)
+
+    def visitDefTag(self, node):
+        if node.is_root() and not node.is_anonymous:
+            self._check_name_exists(self.topleveldefs, node)
+        elif node is not self.node:
+            self._check_name_exists(self.closuredefs, node)
+
+        for ident in node.undeclared_identifiers():
+            if ident != 'context' and\
+                       ident not in self.declared.union(self.locally_declared):
+                self.undeclared.add(ident)
+
+        # visit defs only one level deep
+        if node is self.node:
+            for ident in node.declared_identifiers():
+                self.argument_declared.add(ident)
+
+            for n in node.nodes:
+                n.accept_visitor(self)
+
+    def visitBlockTag(self, node):
+        if node is not self.node and \
+            not node.is_anonymous:
+
+            if isinstance(self.node, parsetree.DefTag):
+                raise exceptions.CompileException(
+                        "Named block '%s' not allowed inside of def '%s'"
+                        % (node.name, self.node.name), **node.exception_kwargs)
+            elif isinstance(self.node,
+                            (parsetree.CallTag, parsetree.CallNamespaceTag)):
+                raise exceptions.CompileException(
+                        "Named block '%s' not allowed inside of <%%call> tag"
+                        % (node.name, ), **node.exception_kwargs)
+
+        for ident in node.undeclared_identifiers():
+            if ident != 'context' and \
+                       ident not in self.declared.union(self.locally_declared):
+                self.undeclared.add(ident)
+
+        if not node.is_anonymous:
+            self._check_name_exists(self.topleveldefs, node)
+            self.undeclared.add(node.funcname)
+        elif node is not self.node:
+            self._check_name_exists(self.closuredefs, node)
+        for ident in node.declared_identifiers():
+            self.argument_declared.add(ident)
+        for n in node.nodes:
+            n.accept_visitor(self)
+
+    def visitTextTag(self, node):
+        for ident in node.undeclared_identifiers():
+            if ident != 'context' and \
+                ident not in self.declared.union(self.locally_declared):
+                self.undeclared.add(ident)
+
+    def visitIncludeTag(self, node):
+        self.check_declared(node)
+
+    def visitPageTag(self, node):
+        for ident in node.declared_identifiers():
+            self.argument_declared.add(ident)
+        self.check_declared(node)
+
+    def visitCallNamespaceTag(self, node):
+        self.visitCallTag(node)
+
+    def visitCallTag(self, node):
+        if node is self.node:
+            for ident in node.undeclared_identifiers():
+                if ident != 'context' and\
+                       ident not in self.declared.union(self.locally_declared):
+                    self.undeclared.add(ident)
+            for ident in node.declared_identifiers():
+                self.argument_declared.add(ident)
+            for n in node.nodes:
+                n.accept_visitor(self)
+        else:
+            for ident in node.undeclared_identifiers():
+                if ident != 'context' and\
+                       ident not in self.declared.union(self.locally_declared):
+                    self.undeclared.add(ident)
+
+
+_FOR_LOOP = re.compile(
+        r'^for\s+((?:\(?)\s*[A-Za-z_][A-Za-z_0-9]*'
+        r'(?:\s*,\s*(?:[A-Za-z_][A-Za-z0-9_]*),??)*\s*(?:\)?))\s+in\s+(.*):'
+    )
+
+def mangle_mako_loop(node, printer):
+    """converts a for loop into a context manager wrapped around a for loop
+    when access to the `loop` variable has been detected in the for loop body
+    """
+    loop_variable = LoopVariable()
+    node.accept_visitor(loop_variable)
+    if loop_variable.detected:
+        node.nodes[-1].has_loop_context = True
+        match = _FOR_LOOP.match(node.text)
+        if match:
+            printer.writelines(
+                    'loop = __M_loop._enter(%s)' % match.group(2),
+                    'try:'
+                    #'with __M_loop(%s) as loop:' % match.group(2)
+                )
+            text = 'for %s in loop:' % match.group(1)
+        else:
+            raise SyntaxError("Couldn't apply loop context: %s" % node.text)
+    else:
+        text = node.text
+    return text
+
+
+class LoopVariable(object):
+    """A node visitor which looks for the name 'loop' within undeclared
+    identifiers."""
+
+    def __init__(self):
+        self.detected = False
+
+    def _loop_reference_detected(self, node):
+        if 'loop' in node.undeclared_identifiers():
+            self.detected = True
+        else:
+            for n in node.get_children():
+                n.accept_visitor(self)
+
+    def visitControlLine(self, node):
+        self._loop_reference_detected(node)
+
+    def visitCode(self, node):
+        self._loop_reference_detected(node)
+
+    def visitExpression(self, node):
+        self._loop_reference_detected(node)
diff --git a/lib3/Mako-0.7.3/mako/exceptions.py b/lib3/Mako-0.7.3/mako/exceptions.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/exceptions.py
@@ -0,0 +1,362 @@
+# mako/exceptions.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""exception classes"""
+
+import traceback, sys, re
+from mako import util
+
+class MakoException(Exception):
+    pass
+
+class RuntimeException(MakoException):
+    pass
+
+def _format_filepos(lineno, pos, filename):
+    if filename is None:
+        return " at line: %d char: %d" % (lineno, pos)
+    else:
+        return " in file '%s' at line: %d char: %d" % (filename, lineno, pos)
+
+
+class CompileException(MakoException):
+    def __init__(self, message, source, lineno, pos, filename):
+        MakoException.__init__(self,
+                              message + _format_filepos(lineno, pos, filename))
+        self.lineno =lineno
+        self.pos = pos
+        self.filename = filename
+        self.source = source
+
+class SyntaxException(MakoException):
+    def __init__(self, message, source, lineno, pos, filename):
+        MakoException.__init__(self,
+                              message + _format_filepos(lineno, pos, filename))
+        self.lineno =lineno
+        self.pos = pos
+        self.filename = filename
+        self.source = source
+
+class UnsupportedError(MakoException):
+    """raised when a retired feature is used."""
+
+class NameConflictError(MakoException):
+    """raised when a reserved word is used inappropriately"""
+
+class TemplateLookupException(MakoException):
+    pass
+
+class TopLevelLookupException(TemplateLookupException):
+    pass
+
+class RichTraceback(object):
+    """Pull the current exception from the ``sys`` traceback and extracts
+    Mako-specific template information.
+
+    See the usage examples in :ref:`handling_exceptions`.
+
+    """
+    def __init__(self, error=None, traceback=None):
+        self.source, self.lineno = "", 0
+
+        if error is None or traceback is None:
+            t, value, tback = sys.exc_info()
+
+        if error is None:
+            error = value or t
+
+        if traceback is None:
+            traceback = tback
+
+        self.error = error
+        self.records = self._init(traceback)
+
+        if isinstance(self.error, (CompileException, SyntaxException)):
+            import mako.template
+            self.source = self.error.source
+            self.lineno = self.error.lineno
+            self._has_source = True
+
+        self._init_message()
+
+    @property
+    def errorname(self):
+        return util.exception_name(self.error)
+
+    def _init_message(self):
+        """Find a unicode representation of self.error"""
+        try:
+            self.message = str(self.error)
+        except UnicodeError:
+            try:
+                self.message = str(self.error)
+            except UnicodeEncodeError:
+                # Fallback to args as neither unicode nor
+                # str(Exception(u'\xe6')) work in Python < 2.6
+                self.message = self.error.args[0]
+        if not isinstance(self.message, str):
+            self.message = str(self.message, 'ascii', 'replace')
+
+    def _get_reformatted_records(self, records):
+        for rec in records:
+            if rec[6] is not None:
+                yield (rec[4], rec[5], rec[2], rec[6])
+            else:
+                yield tuple(rec[0:4])
+
+    @property
+    def traceback(self):
+        """Return a list of 4-tuple traceback records (i.e. normal python
+        format) with template-corresponding lines remapped to the originating
+        template.
+
+        """
+        return list(self._get_reformatted_records(self.records))
+
+    @property
+    def reverse_records(self):
+        return reversed(self.records)
+
+    @property
+    def reverse_traceback(self):
+        """Return the same data as traceback, except in reverse order.
+        """
+
+        return list(self._get_reformatted_records(self.reverse_records))
+
+    def _init(self, trcback):
+        """format a traceback from sys.exc_info() into 7-item tuples,
+        containing the regular four traceback tuple items, plus the original
+        template filename, the line number adjusted relative to the template
+        source, and code line from that line number of the template."""
+
+        import mako.template
+        mods = {}
+        rawrecords = traceback.extract_tb(trcback)
+        new_trcback = []
+        for filename, lineno, function, line in rawrecords:
+            if not line:
+                line = ''
+            try:
+                (line_map, template_lines) = mods[filename]
+            except KeyError:
+                try:
+                    info = mako.template._get_module_info(filename)
+                    module_source = info.code
+                    template_source = info.source
+                    template_filename = info.template_filename or filename
+                except KeyError:
+                    # A normal .py file (not a Template)
+                    if not util.py3k:
+                        try:
+                            fp = open(filename, 'rb')
+                            encoding = util.parse_encoding(fp)
+                            fp.close()
+                        except IOError:
+                            encoding = None
+                        if encoding:
+                            line = line.decode(encoding)
+                        else:
+                            line = line.decode('ascii', 'replace')
+                    new_trcback.append((filename, lineno, function, line,
+                                            None, None, None, None))
+                    continue
+
+                template_ln = module_ln = 1
+                line_map = {}
+                for line in module_source.split("\n"):
+                    match = re.match(r'\s*# SOURCE LINE (\d+)', line)
+                    if match:
+                        template_ln = int(match.group(1))
+                    module_ln += 1
+                    line_map[module_ln] = template_ln
+                template_lines = [line for line in
+                                    template_source.split("\n")]
+                mods[filename] = (line_map, template_lines)
+
+            template_ln = line_map[lineno]
+            if template_ln <= len(template_lines):
+                template_line = template_lines[template_ln - 1]
+            else:
+                template_line = None
+            new_trcback.append((filename, lineno, function,
+                                line, template_filename, template_ln,
+                                template_line, template_source))
+        if not self.source:
+            for l in range(len(new_trcback)-1, 0, -1):
+                if new_trcback[l][5]:
+                    self.source = new_trcback[l][7]
+                    self.lineno = new_trcback[l][5]
+                    break
+            else:
+                if new_trcback:
+                    try:
+                        # A normal .py file (not a Template)
+                        fp = open(new_trcback[-1][0], 'rb')
+                        encoding = util.parse_encoding(fp)
+                        fp.seek(0)
+                        self.source = fp.read()
+                        fp.close()
+                        if encoding:
+                            self.source = self.source.decode(encoding)
+                    except IOError:
+                        self.source = ''
+                    self.lineno = new_trcback[-1][1]
+        return new_trcback
+
+
+def text_error_template(lookup=None):
+    """Provides a template that renders a stack trace in a similar format to
+    the Python interpreter, substituting source template filenames, line
+    numbers and code for that of the originating source template, as
+    applicable.
+
+    """
+    import mako.template
+    return mako.template.Template(r"""
+<%page args="error=None, traceback=None"/>
+<%!
+    from mako.exceptions import RichTraceback
+%>\
+<%
+    tback = RichTraceback(error=error, traceback=traceback)
+%>\
+Traceback (most recent call last):
+% for (filename, lineno, function, line) in tback.traceback:
+  File "${filename}", line ${lineno}, in ${function or '?'}
+    ${line | trim}
+% endfor
+${tback.errorname}: ${tback.message}
+""")
+
+
+try:
+    from mako.ext.pygmentplugin import syntax_highlight,\
+            pygments_html_formatter
+except ImportError:
+    from mako.filters import html_escape
+    pygments_html_formatter = None
+    def syntax_highlight(filename='', language=None):
+        return html_escape
+
+def html_error_template():
+    """Provides a template that renders a stack trace in an HTML format,
+    providing an excerpt of code as well as substituting source template
+    filenames, line numbers and code for that of the originating source
+    template, as applicable.
+
+    The template's default ``encoding_errors`` value is ``'htmlentityreplace'``. The
+    template has two options. With the ``full`` option disabled, only a section of
+    an HTML document is returned. With the ``css`` option disabled, the default
+    stylesheet won't be included.
+
+    """
+    import mako.template
+    return mako.template.Template(r"""
+<%!
+    from mako.exceptions import RichTraceback, syntax_highlight,\
+            pygments_html_formatter
+%>
+<%page args="full=True, css=True, error=None, traceback=None"/>
+% if full:
+<html>
+<head>
+    <title>Mako Runtime Error</title>
+% endif
+% if css:
+    <style>
+        body { font-family:verdana; margin:10px 30px 10px 30px;}
+        .stacktrace { margin:5px 5px 5px 5px; }
+        .highlight { padding:0px 10px 0px 10px; background-color:#9F9FDF; }
+        .nonhighlight { padding:0px; background-color:#DFDFDF; }
+        .sample { padding:10px; margin:10px 10px 10px 10px;
+                  font-family:monospace; }
+        .sampleline { padding:0px 10px 0px 10px; }
+        .sourceline { margin:5px 5px 10px 5px; font-family:monospace;}
+        .location { font-size:80%; }
+        .highlight { white-space:pre; }
+        .sampleline { white-space:pre; }
+
+    % if pygments_html_formatter:
+        ${pygments_html_formatter.get_style_defs()}
+        .linenos { min-width: 2.5em; text-align: right; }
+        pre { margin: 0; }
+        .syntax-highlighted { padding: 0 10px; }
+        .syntax-highlightedtable { border-spacing: 1px; }
+        .nonhighlight { border-top: 1px solid #DFDFDF;
+                        border-bottom: 1px solid #DFDFDF; }
+        .stacktrace .nonhighlight { margin: 5px 15px 10px; }
+        .sourceline { margin: 0 0; font-family:monospace; }
+        .code { background-color: #F8F8F8; width: 100%; }
+        .error .code { background-color: #FFBDBD; }
+        .error .syntax-highlighted { background-color: #FFBDBD; }
+    % endif
+
+    </style>
+% endif
+% if full:
+</head>
+<body>
+% endif
+
+<h2>Error !</h2>
+<%
+    tback = RichTraceback(error=error, traceback=traceback)
+    src = tback.source
+    line = tback.lineno
+    if src:
+        lines = src.split('\n')
+    else:
+        lines = None
+%>
+<h3>${tback.errorname}: ${tback.message|h}</h3>
+
+% if lines:
+    <div class="sample">
+    <div class="nonhighlight">
+% for index in range(max(0, line-4),min(len(lines), line+5)):
+    <%
+       if pygments_html_formatter:
+           pygments_html_formatter.linenostart = index + 1
+    %>
+    % if index + 1 == line:
+    <%
+       if pygments_html_formatter:
+           old_cssclass = pygments_html_formatter.cssclass
+           pygments_html_formatter.cssclass = 'error ' + old_cssclass
+    %>
+        ${lines[index] | syntax_highlight(language='mako')}
+    <%
+       if pygments_html_formatter:
+           pygments_html_formatter.cssclass = old_cssclass
+    %>
+    % else:
+        ${lines[index] | syntax_highlight(language='mako')}
+    % endif
+% endfor
+    </div>
+    </div>
+% endif
+
+<div class="stacktrace">
+% for (filename, lineno, function, line) in tback.reverse_traceback:
+    <div class="location">${filename}, line ${lineno}:</div>
+    <div class="nonhighlight">
+    <%
+       if pygments_html_formatter:
+           pygments_html_formatter.linenostart = lineno
+    %>
+      <div class="sourceline">${line | syntax_highlight(filename)}</div>
+    </div>
+% endfor
+</div>
+
+% if full:
+</body>
+</html>
+% endif
+""", output_encoding=sys.getdefaultencoding(),
+        encoding_errors='htmlentityreplace')
diff --git a/lib3/Mako-0.7.3/mako/ext/__init__.py b/lib3/Mako-0.7.3/mako/ext/__init__.py
new file mode 100644
diff --git a/lib3/Mako-0.7.3/mako/ext/autohandler.py b/lib3/Mako-0.7.3/mako/ext/autohandler.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/ext/autohandler.py
@@ -0,0 +1,65 @@
+# ext/autohandler.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""adds autohandler functionality to Mako templates.
+
+requires that the TemplateLookup class is used with templates.
+
+usage:
+
+<%!
+    from mako.ext.autohandler import autohandler
+%>
+<%inherit file="${autohandler(template, context)}"/>
+
+
+or with custom autohandler filename:
+
+<%!
+    from mako.ext.autohandler import autohandler
+%>
+<%inherit file="${autohandler(template, context, name='somefilename')}"/>
+
+"""
+
+import posixpath, os, re
+
+def autohandler(template, context, name='autohandler'):
+    lookup = context.lookup
+    _template_uri = template.module._template_uri
+    if not lookup.filesystem_checks:
+        try:
+            return lookup._uri_cache[(autohandler, _template_uri, name)]
+        except KeyError:
+            pass
+
+    tokens = re.findall(r'([^/]+)', posixpath.dirname(_template_uri)) + [name]
+    while len(tokens):
+        path = '/' + '/'.join(tokens)
+        if path != _template_uri and _file_exists(lookup, path):
+            if not lookup.filesystem_checks:
+                return lookup._uri_cache.setdefault(
+                            (autohandler, _template_uri, name), path)
+            else:
+                return path
+        if len(tokens) == 1:
+            break
+        tokens[-2:] = [name]
+ 
+    if not lookup.filesystem_checks:
+        return lookup._uri_cache.setdefault(
+                            (autohandler, _template_uri, name), None)
+    else:
+        return None
+
+def _file_exists(lookup, path):
+    psub = re.sub(r'^/', '',path)
+    for d in lookup.directories:
+        if os.path.exists(d + '/' + psub):
+            return True
+    else:
+        return False
+ 
diff --git a/lib3/Mako-0.7.3/mako/ext/babelplugin.py b/lib3/Mako-0.7.3/mako/ext/babelplugin.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/ext/babelplugin.py
@@ -0,0 +1,132 @@
+# ext/babelplugin.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""gettext message extraction via Babel: http://babel.edgewall.org/"""
+from io import StringIO
+
+from babel.messages.extract import extract_python
+
+from mako import lexer, parsetree, util
+
+def extract(fileobj, keywords, comment_tags, options):
+    """Extract messages from Mako templates.
+
+    :param fileobj: the file-like object the messages should be extracted from
+    :param keywords: a list of keywords (i.e. function names) that should be
+                     recognized as translation functions
+    :param comment_tags: a list of translator tags to search for and include
+                         in the results
+    :param options: a dictionary of additional options (optional)
+    :return: an iterator over ``(lineno, funcname, message, comments)`` tuples
+    :rtype: ``iterator``
+    """
+    encoding = options.get('input_encoding', options.get('encoding', None))
+
+    template_node = lexer.Lexer(fileobj.read(),
+                                input_encoding=encoding).parse()
+    for extracted in extract_nodes(template_node.get_children(),
+                                   keywords, comment_tags, options):
+        yield extracted
+
+def extract_nodes(nodes, keywords, comment_tags, options):
+    """Extract messages from Mako's lexer node objects
+
+    :param nodes: an iterable of Mako parsetree.Node objects to extract from
+    :param keywords: a list of keywords (i.e. function names) that should be
+                     recognized as translation functions
+    :param comment_tags: a list of translator tags to search for and include
+                         in the results
+    :param options: a dictionary of additional options (optional)
+    :return: an iterator over ``(lineno, funcname, message, comments)`` tuples
+    :rtype: ``iterator``
+    """
+    translator_comments = []
+    in_translator_comments = False
+
+    for node in nodes:
+        child_nodes = None
+        if in_translator_comments and isinstance(node, parsetree.Text) and \
+                not node.content.strip():
+            # Ignore whitespace within translator comments
+            continue
+
+        if isinstance(node, parsetree.Comment):
+            value = node.text.strip()
+            if in_translator_comments:
+                translator_comments.extend(_split_comment(node.lineno, value))
+                continue
+            for comment_tag in comment_tags:
+                if value.startswith(comment_tag):
+                    in_translator_comments = True
+                    translator_comments.extend(_split_comment(node.lineno,
+                                                              value))
+            continue
+
+        if isinstance(node, parsetree.DefTag):
+            code = node.function_decl.code
+            child_nodes = node.nodes
+        elif isinstance(node, parsetree.BlockTag):
+            code = node.body_decl.code
+            child_nodes = node.nodes
+        elif isinstance(node, parsetree.CallTag):
+            code = node.code.code
+            child_nodes = node.nodes
+        elif isinstance(node, parsetree.PageTag):
+            code = node.body_decl.code
+        elif isinstance(node, parsetree.CallNamespaceTag):
+            attribs = ', '.join(['%s=%s' % (key, val)
+                                 for key, val in node.attributes.items()])
+            code = '{%s}' % attribs
+            child_nodes = node.nodes
+        elif isinstance(node, parsetree.ControlLine):
+            if node.isend:
+                translator_comments = []
+                in_translator_comments = False
+                continue
+            code = node.text
+        elif isinstance(node, parsetree.Code):
+            # <% and <%! blocks would provide their own translator comments
+            translator_comments = []
+            in_translator_comments = False
+
+            code = node.code.code
+        elif isinstance(node, parsetree.Expression):
+            code = node.code.code
+        else:
+            translator_comments = []
+            in_translator_comments = False
+            continue
+
+        # Comments don't apply unless they immediately preceed the message
+        if translator_comments and \
+                translator_comments[-1][0] < node.lineno - 1:
+            translator_comments = []
+        else:
+            translator_comments = \
+                [comment[1] for comment in translator_comments]
+
+        if not util.py3k and isinstance(code, str):
+            code = code.encode('ascii', 'backslashreplace')
+        code = StringIO(code)
+        for lineno, funcname, messages, python_translator_comments \
+                in extract_python(code, keywords, comment_tags, options):
+            yield (node.lineno + (lineno - 1), funcname, messages,
+                   translator_comments + python_translator_comments)
+
+        translator_comments = []
+        in_translator_comments = False
+
+        if child_nodes:
+            for extracted in extract_nodes(child_nodes, keywords, comment_tags,
+                                           options):
+                yield extracted
+
+
+def _split_comment(lineno, comment):
+    """Return the multiline comment at lineno split into a list of comment line
+    numbers and the accompanying comment line"""
+    return [(lineno + index, line) for index, line in
+            enumerate(comment.splitlines())]
diff --git a/lib3/Mako-0.7.3/mako/ext/beaker_cache.py b/lib3/Mako-0.7.3/mako/ext/beaker_cache.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/ext/beaker_cache.py
@@ -0,0 +1,70 @@
+"""Provide a :class:`.CacheImpl` for the Beaker caching system."""
+
+from mako import exceptions
+
+from mako.cache import CacheImpl
+
+_beaker_cache = None
+class BeakerCacheImpl(CacheImpl):
+    """A :class:`.CacheImpl` provided for the Beaker caching system.
+    
+    This plugin is used by default, based on the default
+    value of ``'beaker'`` for the ``cache_impl`` parameter of the
+    :class:`.Template` or :class:`.TemplateLookup` classes.
+    
+    """
+
+    def __init__(self, cache):
+        global _beaker_cache
+        if _beaker_cache is None:
+            try:
+                from beaker import cache as beaker_cache
+            except ImportError as e:
+                raise exceptions.RuntimeException(
+                            "the Beaker package is required to use cache "
+                            "functionality.")
+
+            if 'manager' in cache.template.cache_args:
+                _beaker_cache = cache.template.cache_args['manager']
+            else:
+                _beaker_cache = beaker_cache.CacheManager()
+        super(BeakerCacheImpl, self).__init__(cache)
+
+    def _get_cache(self, **kw):
+        expiretime = kw.pop('timeout', None)
+        if 'dir' in kw:
+            kw['data_dir'] = kw.pop('dir')
+        elif self.cache.template.module_directory:
+            kw['data_dir'] = self.cache.template.module_directory
+
+        if 'manager' in kw:
+            kw.pop('manager')
+
+        if kw.get('type') == 'memcached':
+            kw['type'] = 'ext:memcached'
+
+        if 'region' in kw:
+            region = kw.pop('region')
+            cache = _beaker_cache.get_cache_region(self.cache.id, region, **kw)
+        else:
+            cache = _beaker_cache.get_cache(self.cache.id, **kw)
+        cache_args = {'starttime':self.cache.starttime}
+        if expiretime:
+            cache_args['expiretime'] = expiretime
+        return cache, cache_args
+
+    def get_or_create(self, key, creation_function, **kw):
+        cache, kw = self._get_cache(**kw)
+        return cache.get(key, createfunc=creation_function, **kw)
+
+    def put(self, key, value, **kw):
+        cache, kw = self._get_cache(**kw)
+        cache.put(key, value, **kw)
+ 
+    def get(self, key, **kw):
+        cache, kw = self._get_cache(**kw)
+        return cache.get(key, **kw)
+ 
+    def invalidate(self, key, **kw):
+        cache, kw = self._get_cache(**kw)
+        cache.remove_value(key, **kw)
diff --git a/lib3/Mako-0.7.3/mako/ext/preprocessors.py b/lib3/Mako-0.7.3/mako/ext/preprocessors.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/ext/preprocessors.py
@@ -0,0 +1,20 @@
+# ext/preprocessors.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""preprocessing functions, used with the 'preprocessor' 
+argument on Template, TemplateLookup"""
+
+import re
+
+def convert_comments(text):
+    """preprocess old style comments.
+ 
+    example:
+ 
+    from mako.ext.preprocessors import convert_comments
+    t = Template(..., preprocessor=preprocess_comments)"""
+    return re.sub(r'(?<=\n)\s*#[^#]', "##", text)
+
diff --git a/lib3/Mako-0.7.3/mako/ext/pygmentplugin.py b/lib3/Mako-0.7.3/mako/ext/pygmentplugin.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/ext/pygmentplugin.py
@@ -0,0 +1,122 @@
+# ext/pygmentplugin.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+from pygments.lexers.web import \
+     HtmlLexer, XmlLexer, JavascriptLexer, CssLexer
+from pygments.lexers.agile import PythonLexer, Python3Lexer
+from pygments.lexer import DelegatingLexer, RegexLexer, bygroups, \
+     include, using
+from pygments.token import \
+     Text, Comment, Operator, Keyword, Name, String, Other
+from pygments.formatters.html import HtmlFormatter
+from pygments import highlight
+from mako import util
+
+class MakoLexer(RegexLexer):
+    name = 'Mako'
+    aliases = ['mako']
+    filenames = ['*.mao']
+
+    tokens = {
+        'root': [
+            (r'(\s*)(\%)(\s*end(?:\w+))(\n|\Z)',
+             bygroups(Text, Comment.Preproc, Keyword, Other)),
+            (r'(\s*)(\%(?!%))([^\n]*)(\n|\Z)',
+             bygroups(Text, Comment.Preproc, using(PythonLexer), Other)),
+            (r'(\s*)(##[^\n]*)(\n|\Z)',
+              bygroups(Text, Comment.Preproc, Other)),
+            (r'''(?s)<%doc>.*?</%doc>''', Comment.Preproc),
+            (r'(<%)([\w\.\:]+)',
+              bygroups(Comment.Preproc, Name.Builtin), 'tag'),
+            (r'(</%)([\w\.\:]+)(>)',
+              bygroups(Comment.Preproc, Name.Builtin, Comment.Preproc)),
+            (r'<%(?=([\w\.\:]+))', Comment.Preproc, 'ondeftags'),
+            (r'(<%(?:!?))(.*?)(%>)(?s)',
+              bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)),
+            (r'(\$\{)(.*?)(\})',
+             bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)),
+            (r'''(?sx)
+                (.+?)               # anything, followed by:
+                (?:
+                 (?<=\n)(?=%(?!%)|\#\#) |  # an eval or comment line
+                 (?=\#\*) |          # multiline comment
+                 (?=</?%) |         # a python block
+                                    # call start or end
+                 (?=\$\{) |         # a substitution
+                 (?<=\n)(?=\s*%) |
+                                    # - don't consume
+                 (\\\n) |           # an escaped newline
+                 \Z                 # end of string
+                )
+            ''', bygroups(Other, Operator)),
+            (r'\s+', Text),
+        ],
+        'ondeftags': [
+            (r'<%', Comment.Preproc),
+            (r'(?<=<%)(include|inherit|namespace|page)', Name.Builtin),
+            include('tag'),
+        ],
+        'tag': [
+            (r'((?:\w+)\s*=)\s*(".*?")',
+             bygroups(Name.Attribute, String)),
+            (r'/?\s*>', Comment.Preproc, '#pop'),
+            (r'\s+', Text),
+        ],
+        'attr': [
+            ('".*?"', String, '#pop'),
+            ("'.*?'", String, '#pop'),
+            (r'[^\s>]+', String, '#pop'),
+        ],
+    }
+
+
+class MakoHtmlLexer(DelegatingLexer):
+    name = 'HTML+Mako'
+    aliases = ['html+mako']
+
+    def __init__(self, **options):
+        super(MakoHtmlLexer, self).__init__(HtmlLexer, MakoLexer,
+                                              **options)
+
+class MakoXmlLexer(DelegatingLexer):
+    name = 'XML+Mako'
+    aliases = ['xml+mako']
+
+    def __init__(self, **options):
+        super(MakoXmlLexer, self).__init__(XmlLexer, MakoLexer,
+                                             **options)
+
+class MakoJavascriptLexer(DelegatingLexer):
+    name = 'JavaScript+Mako'
+    aliases = ['js+mako', 'javascript+mako']
+
+    def __init__(self, **options):
+        super(MakoJavascriptLexer, self).__init__(JavascriptLexer,
+                                                    MakoLexer, **options)
+
+class MakoCssLexer(DelegatingLexer):
+    name = 'CSS+Mako'
+    aliases = ['css+mako']
+
+    def __init__(self, **options):
+        super(MakoCssLexer, self).__init__(CssLexer, MakoLexer,
+                                             **options)
+
+
+pygments_html_formatter = HtmlFormatter(cssclass='syntax-highlighted',
+                                        linenos=True)
+def syntax_highlight(filename='', language=None):
+    mako_lexer = MakoLexer()
+    if util.py3k:
+        python_lexer = Python3Lexer()
+    else:
+        python_lexer = PythonLexer()
+    if filename.startswith('memory:') or language == 'mako':
+        return lambda string: highlight(string, mako_lexer,
+                                        pygments_html_formatter)
+    return lambda string: highlight(string, python_lexer,
+                                    pygments_html_formatter)
+
diff --git a/lib3/Mako-0.7.3/mako/ext/turbogears.py b/lib3/Mako-0.7.3/mako/ext/turbogears.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/ext/turbogears.py
@@ -0,0 +1,57 @@
+# ext/turbogears.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+import re, inspect
+from mako.lookup import TemplateLookup
+from mako.template import Template
+
+class TGPlugin(object):
+    """TurboGears compatible Template Plugin."""
+
+    def __init__(self, extra_vars_func=None, options=None, extension='mak'):
+        self.extra_vars_func = extra_vars_func
+        self.extension = extension
+        if not options:
+            options = {}
+
+        # Pull the options out and initialize the lookup
+        lookup_options = {}
+        for k, v in options.items():
+            if k.startswith('mako.'):
+                lookup_options[k[5:]] = v
+            elif k in ['directories', 'filesystem_checks', 'module_directory']:
+                lookup_options[k] = v
+        self.lookup = TemplateLookup(**lookup_options)
+ 
+        self.tmpl_options = {}
+        # transfer lookup args to template args, based on those available
+        # in getargspec
+        for kw in inspect.getargspec(Template.__init__)[0]:
+            if kw in lookup_options:
+                self.tmpl_options[kw] = lookup_options[kw]
+
+    def load_template(self, templatename, template_string=None):
+        """Loads a template from a file or a string"""
+        if template_string is not None:
+            return Template(template_string, **self.tmpl_options)
+        # Translate TG dot notation to normal / template path
+        if '/' not in templatename:
+            templatename = '/' + templatename.replace('.', '/') + '.' +\
+                    self.extension
+
+        # Lookup template
+        return self.lookup.get_template(templatename)
+
+    def render(self, info, format="html", fragment=False, template=None):
+        if isinstance(template, str):
+            template = self.load_template(template)
+
+        # Load extra vars func if provided
+        if self.extra_vars_func:
+            info.update(self.extra_vars_func())
+
+        return template.render(**info)
+
diff --git a/lib3/Mako-0.7.3/mako/filters.py b/lib3/Mako-0.7.3/mako/filters.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/filters.py
@@ -0,0 +1,191 @@
+# mako/filters.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+
+import re, urllib.request, urllib.parse, urllib.error, html.entities, codecs
+from io import StringIO
+from mako import util
+
+xml_escapes = {
+    '&' : '&',
+    '>' : '>',
+    '<' : '<',
+    '"' : '"',   # also " in html-only
+    "'" : '''    # also ' in html-only
+}
+
+# XXX: " is valid in HTML and XML
+#      ' is not valid HTML, but is valid XML
+
+LEGACY_HTML_ESCAPE_RE = re.compile(r'([&<"\'>])')
+
+def legacy_html_escape(string):
+    """legacy HTML escape for non-unicode mode."""
+
+    return LEGACY_HTML_ESCAPE_RE.sub(lambda m: xml_escapes[m.group()], string)
+
+try:
+    import markupsafe
+    html_escape = markupsafe.escape
+except ImportError:
+    html_escape = legacy_html_escape
+
+
+def xml_escape(string):
+    return re.sub(r'([&<"\'>])', lambda m: xml_escapes[m.group()], string)
+
+def url_escape(string):
+    # convert into a list of octets
+    string = string.encode("utf8")
+    return urllib.parse.quote_plus(string)
+
+def url_unescape(string):
+    text = urllib.parse.unquote_plus(string)
+    if not is_ascii_str(text):
+        text = text.decode("utf8")
+    return text
+
+def trim(string):
+    return string.strip()
+
+
+class Decode(object):
+    def __getattr__(self, key):
+        def decode(x):
+            if isinstance(x, str):
+                return x
+            elif not isinstance(x, str):
+                return str(str(x), encoding=key)
+            else:
+                return str(x, encoding=key)
+        return decode
+decode = Decode()
+
+
+_ASCII_re = re.compile(r'\A[\x00-\x7f]*\Z')
+
+def is_ascii_str(text):
+    return isinstance(text, str) and _ASCII_re.match(text)
+
+################################################################
+
+class XMLEntityEscaper(object):
+    def __init__(self, codepoint2name, name2codepoint):
+        self.codepoint2entity = dict([(c, '&%s;' % n)
+                                      for c,n in codepoint2name.items()])
+        self.name2codepoint = name2codepoint
+
+    def escape_entities(self, text):
+        """Replace characters with their character entity references.
+
+        Only characters corresponding to a named entity are replaced.
+        """
+        return str(text).translate(self.codepoint2entity)
+
+    def __escape(self, m):
+        codepoint = ord(m.group())
+        try:
+            return self.codepoint2entity[codepoint]
+        except (KeyError, IndexError):
+            return '&#x%X;' % codepoint
+
+
+    __escapable = re.compile(r'["&<>]|[^\x00-\x7f]')
+
+    def escape(self, text):
+        """Replace characters with their character references.
+
+        Replace characters by their named entity references.
+        Non-ASCII characters, if they do not have a named entity reference,
+        are replaced by numerical character references.
+
+        The return value is guaranteed to be ASCII.
+        """
+        return self.__escapable.sub(self.__escape, str(text)
+                                    ).encode('ascii')
+
+    # XXX: This regexp will not match all valid XML entity names__.
+    # (It punts on details involving involving CombiningChars and Extenders.)
+    #
+    # .. __: http://www.w3.org/TR/2000/REC-xml-20001006#NT-EntityRef
+    __characterrefs = re.compile(r'''& (?:
+                                          \#(\d+)
+                                          | \#x([\da-f]+)
+                                          | ( (?!\d) [:\w] [-.:\w]+ )
+                                          ) ;''',
+                                 re.X | re.UNICODE)
+
+    def __unescape(self, m):
+        dval, hval, name = m.groups()
+        if dval:
+            codepoint = int(dval)
+        elif hval:
+            codepoint = int(hval, 16)
+        else:
+            codepoint = self.name2codepoint.get(name, 0xfffd)
+            # U+FFFD = "REPLACEMENT CHARACTER"
+        if codepoint < 128:
+            return chr(codepoint)
+        return chr(codepoint)
+
+    def unescape(self, text):
+        """Unescape character references.
+
+        All character references (both entity references and numerical
+        character references) are unescaped.
+        """
+        return self.__characterrefs.sub(self.__unescape, text)
+
+
+_html_entities_escaper = XMLEntityEscaper(html.entities.codepoint2name,
+                                          html.entities.name2codepoint)
+
+html_entities_escape = _html_entities_escaper.escape_entities
+html_entities_unescape = _html_entities_escaper.unescape
+
+
+def htmlentityreplace_errors(ex):
+    """An encoding error handler.
+
+    This python `codecs`_ error handler replaces unencodable
+    characters with HTML entities, or, if no HTML entity exists for
+    the character, XML character references.
+
+    >>> u'The cost was \u20ac12.'.encode('latin1', 'htmlentityreplace')
+    'The cost was €12.'
+    """
+    if isinstance(ex, UnicodeEncodeError):
+        # Handle encoding errors
+        bad_text = ex.object[ex.start:ex.end]
+        text = _html_entities_escaper.escape(bad_text)
+        return (str(text), ex.end)
+    raise ex
+
+codecs.register_error('htmlentityreplace', htmlentityreplace_errors)
+
+
+# TODO: options to make this dynamic per-compilation will be added in a later
+# release
+DEFAULT_ESCAPES = {
+    'x':'filters.xml_escape',
+    'h':'filters.html_escape',
+    'u':'filters.url_escape',
+    'trim':'filters.trim',
+    'entity':'filters.html_entities_escape',
+    'unicode':'unicode',
+    'decode':'decode',
+    'str':'str',
+    'n':'n'
+}
+
+if util.py3k:
+    DEFAULT_ESCAPES.update({
+        'unicode':'str'
+    })
+
+NON_UNICODE_ESCAPES = DEFAULT_ESCAPES.copy()
+NON_UNICODE_ESCAPES['h'] = 'filters.legacy_html_escape'
+
diff --git a/lib3/Mako-0.7.3/mako/lexer.py b/lib3/Mako-0.7.3/mako/lexer.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/lexer.py
@@ -0,0 +1,442 @@
+# mako/lexer.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""provides the Lexer class for parsing template strings into parse trees."""
+
+import re, codecs
+from mako import parsetree, exceptions, util
+from mako.pygen import adjust_whitespace
+
+_regexp_cache = {}
+
+class Lexer(object):
+    def __init__(self, text, filename=None,
+                        disable_unicode=False,
+                        input_encoding=None, preprocessor=None):
+        self.text = text
+        self.filename = filename
+        self.template = parsetree.TemplateNode(self.filename)
+        self.matched_lineno = 1
+        self.matched_charpos = 0
+        self.lineno = 1
+        self.match_position = 0
+        self.tag = []
+        self.control_line = []
+        self.ternary_stack = []
+        self.disable_unicode = disable_unicode
+        self.encoding = input_encoding
+
+        if util.py3k and disable_unicode:
+            raise exceptions.UnsupportedError(
+                                    "Mako for Python 3 does not "
+                                    "support disabling Unicode")
+
+        if preprocessor is None:
+            self.preprocessor = []
+        elif not hasattr(preprocessor, '__iter__'):
+            self.preprocessor = [preprocessor]
+        else:
+            self.preprocessor = preprocessor
+
+    @property
+    def exception_kwargs(self):
+        return {'source':self.text,
+                'lineno':self.matched_lineno,
+                'pos':self.matched_charpos,
+                'filename':self.filename}
+
+    def match(self, regexp, flags=None):
+        """compile the given regexp, cache the reg, and call match_reg()."""
+
+        try:
+            reg = _regexp_cache[(regexp, flags)]
+        except KeyError:
+            if flags:
+                reg = re.compile(regexp, flags)
+            else:
+                reg = re.compile(regexp)
+            _regexp_cache[(regexp, flags)] = reg
+
+        return self.match_reg(reg)
+
+    def match_reg(self, reg):
+        """match the given regular expression object to the current text
+        position.
+
+        if a match occurs, update the current text and line position.
+
+        """
+
+        mp = self.match_position
+
+        match = reg.match(self.text, self.match_position)
+        if match:
+            (start, end) = match.span()
+            if end == start:
+                self.match_position = end + 1
+            else:
+                self.match_position = end
+            self.matched_lineno = self.lineno
+            lines = re.findall(r"\n", self.text[mp:self.match_position])
+            cp = mp - 1
+            while (cp >= 0 and cp<self.textlength and self.text[cp] != '\n'):
+                cp -=1
+            self.matched_charpos = mp - cp
+            self.lineno += len(lines)
+            #print "MATCHED:", match.group(0), "LINE START:",
+            # self.matched_lineno, "LINE END:", self.lineno
+        #print "MATCH:", regexp, "\n", self.text[mp : mp + 15], \
+        #          (match and "TRUE" or "FALSE")
+        return match
+
+    def parse_until_text(self, *text):
+        startpos = self.match_position
+        text_re = r'|'.join(text)
+        brace_level = 0
+        while True:
+            match = self.match(r'#.*\n')
+            if match:
+                continue
+            match = self.match(r'(\"\"\"|\'\'\'|\"|\')((?<!\\)\\\1|.)*?\1',
+                               re.S)
+            if match:
+                continue
+            match = self.match(r'(%s)' % text_re)
+            if match:
+                if match.group(1) == '}' and brace_level > 0:
+                    brace_level -= 1
+                    continue
+                return \
+                    self.text[startpos:\
+                              self.match_position-len(match.group(1))],\
+                    match.group(1)
+            match = self.match(r"(.*?)(?=\"|\'|#|%s)" % text_re, re.S)
+            if match:
+                brace_level += match.group(1).count('{')
+                brace_level -= match.group(1).count('}')
+                continue
+            raise exceptions.SyntaxException(
+                        "Expected: %s" %
+                        ','.join(text),
+                        **self.exception_kwargs)
+
+    def append_node(self, nodecls, *args, **kwargs):
+        kwargs.setdefault('source', self.text)
+        kwargs.setdefault('lineno', self.matched_lineno)
+        kwargs.setdefault('pos', self.matched_charpos)
+        kwargs['filename'] = self.filename
+        node = nodecls(*args, **kwargs)
+        if len(self.tag):
+            self.tag[-1].nodes.append(node)
+        else:
+            self.template.nodes.append(node)
+        # build a set of child nodes for the control line
+        # (used for loop variable detection)
+        # also build a set of child nodes on ternary control lines
+        # (used for determining if a pass needs to be auto-inserted
+        if self.control_line:
+            control_frame = self.control_line[-1]
+            control_frame.nodes.append(node)
+            if not (isinstance(node, parsetree.ControlLine) and
+                    control_frame.is_ternary(node.keyword)):
+                if self.ternary_stack and self.ternary_stack[-1]:
+                    self.ternary_stack[-1][-1].nodes.append(node)
+        if isinstance(node, parsetree.Tag):
+            if len(self.tag):
+                node.parent = self.tag[-1]
+            self.tag.append(node)
+        elif isinstance(node, parsetree.ControlLine):
+            if node.isend:
+                self.control_line.pop()
+                self.ternary_stack.pop()
+            elif node.is_primary:
+                self.control_line.append(node)
+                self.ternary_stack.append([])
+            elif self.control_line and \
+                    self.control_line[-1].is_ternary(node.keyword):
+                self.ternary_stack[-1].append(node)
+            elif self.control_line and \
+                    not self.control_line[-1].is_ternary(node.keyword):
+                raise exceptions.SyntaxException(
+                          "Keyword '%s' not a legal ternary for keyword '%s'" %
+                          (node.keyword, self.control_line[-1].keyword),
+                          **self.exception_kwargs)
+
+    _coding_re = re.compile(r'#.*coding[:=]\s*([-\w.]+).*\r?\n')
+
+    def decode_raw_stream(self, text, decode_raw, known_encoding, filename):
+        """given string/unicode or bytes/string, determine encoding
+           from magic encoding comment, return body as unicode
+           or raw if decode_raw=False
+
+        """
+        if isinstance(text, str):
+            m = self._coding_re.match(text)
+            encoding = m and m.group(1) or known_encoding or 'ascii'
+            return encoding, text
+
+        if text.startswith(codecs.BOM_UTF8):
+            text = text[len(codecs.BOM_UTF8):]
+            parsed_encoding = 'utf-8'
+            m = self._coding_re.match(text.decode('utf-8', 'ignore'))
+            if m is not None and m.group(1) != 'utf-8':
+                raise exceptions.CompileException(
+                                "Found utf-8 BOM in file, with conflicting "
+                                "magic encoding comment of '%s'" % m.group(1),
+                                text.decode('utf-8', 'ignore'),
+                                0, 0, filename)
+        else:
+            m = self._coding_re.match(text.decode('utf-8', 'ignore'))
+            if m:
+                parsed_encoding = m.group(1)
+            else:
+                parsed_encoding = known_encoding or 'ascii'
+
+        if decode_raw:
+            try:
+                text = text.decode(parsed_encoding)
+            except UnicodeDecodeError as e:
+                raise exceptions.CompileException(
+                           "Unicode decode operation of encoding '%s' failed" %
+                           parsed_encoding,
+                           text.decode('utf-8', 'ignore'),
+                           0, 0, filename)
+
+        return parsed_encoding, text
+
+    def parse(self):
+        self.encoding, self.text = self.decode_raw_stream(self.text,
+                                        not self.disable_unicode,
+                                        self.encoding,
+                                        self.filename,)
+
+        for preproc in self.preprocessor:
+            self.text = preproc(self.text)
+
+        # push the match marker past the
+        # encoding comment.
+        self.match_reg(self._coding_re)
+
+        self.textlength = len(self.text)
+
+        while (True):
+            if self.match_position > self.textlength:
+                break
+
+            if self.match_end():
+                break
+            if self.match_expression():
+                continue
+            if self.match_control_line():
+                continue
+            if self.match_comment():
+                continue
+            if self.match_tag_start():
+                continue
+            if self.match_tag_end():
+                continue
+            if self.match_python_block():
+                continue
+            if self.match_text():
+                continue
+
+            if self.match_position > self.textlength:
+                break
+            raise exceptions.CompileException("assertion failed")
+
+        if len(self.tag):
+            raise exceptions.SyntaxException("Unclosed tag: <%%%s>" %
+                                                self.tag[-1].keyword,
+                                                **self.exception_kwargs)
+        if len(self.control_line):
+            raise exceptions.SyntaxException(
+                                      "Unterminated control keyword: '%s'" %
+                                      self.control_line[-1].keyword,
+                                      self.text,
+                                      self.control_line[-1].lineno,
+                                      self.control_line[-1].pos, self.filename)
+        return self.template
+
+    def match_tag_start(self):
+        match = self.match(r'''
+            \<%     # opening tag
+
+            ([\w\.\:]+)   # keyword
+
+            ((?:\s+\w+|\s*=\s*|".*?"|'.*?')*)  # attrname, = \
+                                               #        sign, string expression
+
+            \s*     # more whitespace
+
+            (/)?>   # closing
+
+            ''',
+
+            re.I | re.S | re.X)
+
+        if match:
+            keyword, attr, isend = match.groups()
+            self.keyword = keyword
+            attributes = {}
+            if attr:
+                for att in re.findall(
+                           r"\s*(\w+)\s*=\s*(?:'([^']*)'|\"([^\"]*)\")", attr):
+                    key, val1, val2 = att
+                    text = val1 or val2
+                    text = text.replace('\r\n', '\n')
+                    attributes[key] = text
+            self.append_node(parsetree.Tag, keyword, attributes)
+            if isend:
+                self.tag.pop()
+            else:
+                if keyword == 'text':
+                    match = self.match(r'(.*?)(?=\</%text>)',  re.S)
+                    if not match:
+                        raise exceptions.SyntaxException(
+                                            "Unclosed tag: <%%%s>" %
+                                            self.tag[-1].keyword,
+                                            **self.exception_kwargs)
+                    self.append_node(parsetree.Text, match.group(1))
+                    return self.match_tag_end()
+            return True
+        else:
+            return False
+
+    def match_tag_end(self):
+        match = self.match(r'\</%[\t ]*(.+?)[\t ]*>')
+        if match:
+            if not len(self.tag):
+                raise exceptions.SyntaxException(
+                                   "Closing tag without opening tag: </%%%s>" %
+                                    match.group(1),
+                                    **self.exception_kwargs)
+            elif self.tag[-1].keyword != match.group(1):
+                raise exceptions.SyntaxException(
+                             "Closing tag </%%%s> does not match tag: <%%%s>" %
+                             (match.group(1), self.tag[-1].keyword),
+                             **self.exception_kwargs)
+            self.tag.pop()
+            return True
+        else:
+            return False
+
+    def match_end(self):
+        match = self.match(r'\Z', re.S)
+        if match:
+            string = match.group()
+            if string:
+                return string
+            else:
+                return True
+        else:
+            return False
+
+    def match_text(self):
+        match = self.match(r"""
+                (.*?)         # anything, followed by:
+                (
+                 (?<=\n)(?=[ \t]*(?=%|\#\#)) # an eval or line-based
+                                             # comment preceded by a
+                                             # consumed newline and whitespace
+                 |
+                 (?=\${)      # an expression
+                 |
+                 (?=\#\*)     # multiline comment
+                 |
+                 (?=</?[%&])  # a substitution or block or call start or end
+                              # - don't consume
+                 |
+                 (\\\r?\n)    # an escaped newline  - throw away
+                 |
+                 \Z           # end of string
+                )""", re.X | re.S)
+
+        if match:
+            text = match.group(1)
+            if text:
+                self.append_node(parsetree.Text, text)
+            return True
+        else:
+            return False
+
+    def match_python_block(self):
+        match = self.match(r"<%(!)?")
+        if match:
+            line, pos = self.matched_lineno, self.matched_charpos
+            text, end = self.parse_until_text(r'%>')
+            # the trailing newline helps
+            # compiler.parse() not complain about indentation
+            text = adjust_whitespace(text) + "\n"
+            self.append_node(
+                            parsetree.Code,
+                            text,
+                            match.group(1)=='!', lineno=line, pos=pos)
+            return True
+        else:
+            return False
+
+    def match_expression(self):
+        match = self.match(r"\${")
+        if match:
+            line, pos = self.matched_lineno, self.matched_charpos
+            text, end = self.parse_until_text(r'\|', r'}')
+            if end == '|':
+                escapes, end = self.parse_until_text(r'}')
+            else:
+                escapes = ""
+            text = text.replace('\r\n', '\n')
+            self.append_node(
+                            parsetree.Expression,
+                            text, escapes.strip(),
+                            lineno=line, pos=pos)
+            return True
+        else:
+            return False
+
+    def match_control_line(self):
+        match = self.match(
+                      r"(?<=^)[\t ]*(%(?!%)|##)[\t ]*((?:(?:\\r?\n)|[^\r\n])*)"
+                      r"(?:\r?\n|\Z)", re.M)
+        if match:
+            operator = match.group(1)
+            text = match.group(2)
+            if operator == '%':
+                m2 = re.match(r'(end)?(\w+)\s*(.*)', text)
+                if not m2:
+                    raise exceptions.SyntaxException(
+                                "Invalid control line: '%s'" %
+                                text,
+                                **self.exception_kwargs)
+                isend, keyword = m2.group(1, 2)
+                isend = (isend is not None)
+
+                if isend:
+                    if not len(self.control_line):
+                        raise exceptions.SyntaxException(
+                                "No starting keyword '%s' for '%s'" %
+                                (keyword, text),
+                                **self.exception_kwargs)
+                    elif self.control_line[-1].keyword != keyword:
+                        raise exceptions.SyntaxException(
+                                "Keyword '%s' doesn't match keyword '%s'" %
+                                (text, self.control_line[-1].keyword),
+                                **self.exception_kwargs)
+                self.append_node(parsetree.ControlLine, keyword, isend, text)
+            else:
+                self.append_node(parsetree.Comment, text)
+            return True
+        else:
+            return False
+
+    def match_comment(self):
+        """matches the multiline version of a comment"""
+        match = self.match(r"<%doc>(.*?)</%doc>", re.S)
+        if match:
+            self.append_node(parsetree.Comment, match.group(1))
+            return True
+        else:
+            return False
+
diff --git a/lib3/Mako-0.7.3/mako/lookup.py b/lib3/Mako-0.7.3/mako/lookup.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/lookup.py
@@ -0,0 +1,354 @@
+# mako/lookup.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+import os, stat, posixpath, re
+from mako import exceptions, util
+from mako.template import Template
+
+try:
+    import threading
+except:
+    import dummy_threading as threading
+
+class TemplateCollection(object):
+    """Represent a collection of :class:`.Template` objects,
+    identifiable via URI.
+
+    A :class:`.TemplateCollection` is linked to the usage of
+    all template tags that address other templates, such
+    as ``<%include>``, ``<%namespace>``, and ``<%inherit>``.
+    The ``file`` attribute of each of those tags refers
+    to a string URI that is passed to that :class:`.Template`
+    object's :class:`.TemplateCollection` for resolution.
+
+    :class:`.TemplateCollection` is an abstract class,
+    with the usual default implementation being :class:`.TemplateLookup`.
+
+     """
+
+    def has_template(self, uri):
+        """Return ``True`` if this :class:`.TemplateLookup` is
+        capable of returning a :class:`.Template` object for the
+        given ``uri``.
+
+        :param uri: String URI of the template to be resolved.
+
+        """
+        try:
+            self.get_template(uri)
+            return True
+        except exceptions.TemplateLookupException:
+            return False
+
+    def get_template(self, uri, relativeto=None):
+        """Return a :class:`.Template` object corresponding to the given
+        ``uri``.
+
+        The default implementation raises
+        :class:`.NotImplementedError`. Implementations should
+        raise :class:`.TemplateLookupException` if the given ``uri``
+        cannot be resolved.
+
+        :param uri: String URI of the template to be resolved.
+        :param relativeto: if present, the given ``uri`` is assumed to
+         be relative to this URI.
+
+        """
+        raise NotImplementedError()
+
+    def filename_to_uri(self, uri, filename):
+        """Convert the given ``filename`` to a URI relative to
+           this :class:`.TemplateCollection`."""
+
+        return uri
+
+    def adjust_uri(self, uri, filename):
+        """Adjust the given ``uri`` based on the calling ``filename``.
+
+        When this method is called from the runtime, the
+        ``filename`` parameter is taken directly to the ``filename``
+        attribute of the calling template. Therefore a custom
+        :class:`.TemplateCollection` subclass can place any string
+        identifier desired in the ``filename`` parameter of the
+        :class:`.Template` objects it constructs and have them come back
+        here.
+
+        """
+        return uri
+
+class TemplateLookup(TemplateCollection):
+    """Represent a collection of templates that locates template source files
+    from the local filesystem.
+
+    The primary argument is the ``directories`` argument, the list of
+    directories to search:
+
+    .. sourcecode:: python
+
+        lookup = TemplateLookup(["/path/to/templates"])
+        some_template = lookup.get_template("/index.html")
+
+    The :class:`.TemplateLookup` can also be given :class:`.Template` objects
+    programatically using :meth:`.put_string` or :meth:`.put_template`:
+
+    .. sourcecode:: python
+
+        lookup = TemplateLookup()
+        lookup.put_string("base.html", '''
+            <html><body>${self.next()}</body></html>
+        ''')
+        lookup.put_string("hello.html", '''
+            <%include file='base.html'/>
+
+            Hello, world !
+        ''')
+
+
+    :param directories: A list of directory names which will be
+     searched for a particular template URI. The URI is appended
+     to each directory and the filesystem checked.
+
+    :param collection_size: Approximate size of the collection used
+     to store templates. If left at its default of ``-1``, the size
+     is unbounded, and a plain Python dictionary is used to
+     relate URI strings to :class:`.Template` instances.
+     Otherwise, a least-recently-used cache object is used which
+     will maintain the size of the collection approximately to
+     the number given.
+
+    :param filesystem_checks: When at its default value of ``True``,
+     each call to :meth:`.TemplateLookup.get_template()` will
+     compare the filesystem last modified time to the time in
+     which an existing :class:`.Template` object was created.
+     This allows the :class:`.TemplateLookup` to regenerate a
+     new :class:`.Template` whenever the original source has
+     been updated. Set this to ``False`` for a very minor
+     performance increase.
+
+    :param modulename_callable: A callable which, when present,
+     is passed the path of the source file as well as the
+     requested URI, and then returns the full path of the
+     generated Python module file. This is used to inject
+     alternate schemes for Python module location. If left at
+     its default of ``None``, the built in system of generation
+     based on ``module_directory`` plus ``uri`` is used.
+
+    All other keyword parameters available for
+    :class:`.Template` are mirrored here. When new
+    :class:`.Template` objects are created, the keywords
+    established with this :class:`.TemplateLookup` are passed on
+    to each new :class:`.Template`.
+
+    """
+
+    def __init__(self,
+                        directories=None,
+                        module_directory=None,
+                        filesystem_checks=True,
+                        collection_size=-1,
+                        format_exceptions=False,
+                        error_handler=None,
+                        disable_unicode=False,
+                        bytestring_passthrough=False,
+                        output_encoding=None,
+                        encoding_errors='strict',
+
+                        cache_args=None,
+                        cache_impl='beaker',
+                        cache_enabled=True,
+                        cache_type=None,
+                        cache_dir=None,
+                        cache_url=None,
+
+                        modulename_callable=None,
+                        module_writer=None,
+                        default_filters=None,
+                        buffer_filters=(),
+                        strict_undefined=False,
+                        imports=None,
+                        enable_loop=True,
+                        input_encoding=None,
+                        preprocessor=None):
+
+        self.directories = [posixpath.normpath(d) for d in
+                            util.to_list(directories, ())
+                            ]
+        self.module_directory = module_directory
+        self.modulename_callable = modulename_callable
+        self.filesystem_checks = filesystem_checks
+        self.collection_size = collection_size
+
+        if cache_args is None:
+            cache_args = {}
+        # transfer deprecated cache_* args
+        if cache_dir:
+            cache_args.setdefault('dir', cache_dir)
+        if cache_url:
+            cache_args.setdefault('url', cache_url)
+        if cache_type:
+            cache_args.setdefault('type', cache_type)
+
+        self.template_args = {
+            'format_exceptions':format_exceptions,
+            'error_handler':error_handler,
+            'disable_unicode':disable_unicode,
+            'bytestring_passthrough':bytestring_passthrough,
+            'output_encoding':output_encoding,
+            'cache_impl':cache_impl,
+            'encoding_errors':encoding_errors,
+            'input_encoding':input_encoding,
+            'module_directory':module_directory,
+            'module_writer':module_writer,
+            'cache_args':cache_args,
+            'cache_enabled':cache_enabled,
+            'default_filters':default_filters,
+            'buffer_filters':buffer_filters,
+            'strict_undefined':strict_undefined,
+            'imports':imports,
+            'enable_loop':enable_loop,
+            'preprocessor':preprocessor}
+
+        if collection_size == -1:
+            self._collection = {}
+            self._uri_cache = {}
+        else:
+            self._collection = util.LRUCache(collection_size)
+            self._uri_cache = util.LRUCache(collection_size)
+        self._mutex = threading.Lock()
+
+    def get_template(self, uri):
+        """Return a :class:`.Template` object corresponding to the given
+        ``uri``.
+
+        .. note:: The ``relativeto`` argument is not supported here at the moment.
+
+        """
+
+        try:
+            if self.filesystem_checks:
+                return self._check(uri, self._collection[uri])
+            else:
+                return self._collection[uri]
+        except KeyError:
+            u = re.sub(r'^\/+', '', uri)
+            for dir in self.directories:
+                srcfile = posixpath.normpath(posixpath.join(dir, u))
+                if os.path.isfile(srcfile):
+                    return self._load(srcfile, uri)
+            else:
+                raise exceptions.TopLevelLookupException(
+                                    "Cant locate template for uri %r" % uri)
+
+    def adjust_uri(self, uri, relativeto):
+        """Adjust the given ``uri`` based on the given relative URI."""
+
+        key = (uri, relativeto)
+        if key in self._uri_cache:
+            return self._uri_cache[key]
+
+        if uri[0] != '/':
+            if relativeto is not None:
+                v = self._uri_cache[key] = posixpath.join(
+                                            posixpath.dirname(relativeto), uri)
+            else:
+                v = self._uri_cache[key] = '/' + uri
+        else:
+            v = self._uri_cache[key] = uri
+        return v
+
+
+    def filename_to_uri(self, filename):
+        """Convert the given ``filename`` to a URI relative to
+           this :class:`.TemplateCollection`."""
+
+        try:
+            return self._uri_cache[filename]
+        except KeyError:
+            value = self._relativeize(filename)
+            self._uri_cache[filename] = value
+            return value
+
+    def _relativeize(self, filename):
+        """Return the portion of a filename that is 'relative'
+           to the directories in this lookup.
+
+        """
+
+        filename = posixpath.normpath(filename)
+        for dir in self.directories:
+            if filename[0:len(dir)] == dir:
+                return filename[len(dir):]
+        else:
+            return None
+
+    def _load(self, filename, uri):
+        self._mutex.acquire()
+        try:
+            try:
+                # try returning from collection one
+                # more time in case concurrent thread already loaded
+                return self._collection[uri]
+            except KeyError:
+                pass
+            try:
+                if self.modulename_callable is not None:
+                    module_filename = self.modulename_callable(filename, uri)
+                else:
+                    module_filename = None
+                self._collection[uri] = template = Template(
+                                        uri=uri,
+                                        filename=posixpath.normpath(filename),
+                                        lookup=self,
+                                        module_filename=module_filename,
+                                        **self.template_args)
+                return template
+            except:
+                # if compilation fails etc, ensure
+                # template is removed from collection,
+                # re-raise
+                self._collection.pop(uri, None)
+                raise
+        finally:
+            self._mutex.release()
+
+    def _check(self, uri, template):
+        if template.filename is None:
+            return template
+
+        try:
+            template_stat = os.stat(template.filename)
+            if template.module._modified_time < \
+                        template_stat[stat.ST_MTIME]:
+                self._collection.pop(uri, None)
+                return self._load(template.filename, uri)
+            else:
+                return template
+        except OSError:
+            self._collection.pop(uri, None)
+            raise exceptions.TemplateLookupException(
+                                "Cant locate template for uri %r" % uri)
+
+
+    def put_string(self, uri, text):
+        """Place a new :class:`.Template` object into this
+        :class:`.TemplateLookup`, based on the given string of
+        ``text``.
+
+        """
+        self._collection[uri] = Template(
+                                    text,
+                                    lookup=self,
+                                    uri=uri,
+                                    **self.template_args)
+
+    def put_template(self, uri, template):
+        """Place a new :class:`.Template` object into this
+        :class:`.TemplateLookup`, based on the given
+        :class:`.Template` object.
+
+        """
+        self._collection[uri] = template
+
diff --git a/lib3/Mako-0.7.3/mako/parsetree.py b/lib3/Mako-0.7.3/mako/parsetree.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/parsetree.py
@@ -0,0 +1,594 @@
+# mako/parsetree.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""defines the parse tree components for Mako templates."""
+
+from mako import exceptions, ast, util, filters
+import re
+
+class Node(object):
+    """base class for a Node in the parse tree."""
+
+    def __init__(self, source, lineno, pos, filename):
+        self.source = source
+        self.lineno = lineno
+        self.pos = pos
+        self.filename = filename
+
+    @property
+    def exception_kwargs(self):
+        return {'source':self.source, 'lineno':self.lineno,
+                'pos':self.pos, 'filename':self.filename}
+
+    def get_children(self):
+        return []
+
+    def accept_visitor(self, visitor):
+        def traverse(node):
+            for n in node.get_children():
+                n.accept_visitor(visitor)
+
+        method = getattr(visitor, "visit" + self.__class__.__name__, traverse)
+        method(self)
+
+class TemplateNode(Node):
+    """a 'container' node that stores the overall collection of nodes."""
+
+    def __init__(self, filename):
+        super(TemplateNode, self).__init__('', 0, 0, filename)
+        self.nodes = []
+        self.page_attributes = {}
+
+    def get_children(self):
+        return self.nodes
+
+    def __repr__(self):
+        return "TemplateNode(%s, %r)" % (
+                    util.sorted_dict_repr(self.page_attributes),
+                    self.nodes)
+
+class ControlLine(Node):
+    """defines a control line, a line-oriented python line or end tag.
+
+    e.g.::
+
+        % if foo:
+            (markup)
+        % endif
+
+    """
+
+    has_loop_context = False
+
+    def __init__(self, keyword, isend, text, **kwargs):
+        super(ControlLine, self).__init__(**kwargs)
+        self.text = text
+        self.keyword = keyword
+        self.isend = isend
+        self.is_primary = keyword in ['for', 'if', 'while', 'try', 'with']
+        self.nodes = []
+        if self.isend:
+            self._declared_identifiers = []
+            self._undeclared_identifiers = []
+        else:
+            code = ast.PythonFragment(text, **self.exception_kwargs)
+            self._declared_identifiers = code.declared_identifiers
+            self._undeclared_identifiers = code.undeclared_identifiers
+
+    def get_children(self):
+        return self.nodes
+
+    def declared_identifiers(self):
+        return self._declared_identifiers
+
+    def undeclared_identifiers(self):
+        return self._undeclared_identifiers
+
+    def is_ternary(self, keyword):
+        """return true if the given keyword is a ternary keyword
+        for this ControlLine"""
+
+        return keyword in {
+            'if':set(['else', 'elif']),
+            'try':set(['except', 'finally']),
+            'for':set(['else'])
+        }.get(self.keyword, [])
+
+    def __repr__(self):
+        return "ControlLine(%r, %r, %r, %r)" % (
+            self.keyword,
+            self.text,
+            self.isend,
+            (self.lineno, self.pos)
+        )
+
+class Text(Node):
+    """defines plain text in the template."""
+
+    def __init__(self, content, **kwargs):
+        super(Text, self).__init__(**kwargs)
+        self.content = content
+
+    def __repr__(self):
+        return "Text(%r, %r)" % (self.content, (self.lineno, self.pos))
+
+class Code(Node):
+    """defines a Python code block, either inline or module level.
+
+    e.g.::
+
+        inline:
+        <%
+            x = 12
+        %>
+
+        module level:
+        <%!
+            import logger
+        %>
+
+    """
+
+    def __init__(self, text, ismodule, **kwargs):
+        super(Code, self).__init__(**kwargs)
+        self.text = text
+        self.ismodule = ismodule
+        self.code = ast.PythonCode(text, **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return self.code.declared_identifiers
+
+    def undeclared_identifiers(self):
+        return self.code.undeclared_identifiers
+
+    def __repr__(self):
+        return "Code(%r, %r, %r)" % (
+            self.text,
+            self.ismodule,
+            (self.lineno, self.pos)
+        )
+
+class Comment(Node):
+    """defines a comment line.
+
+    # this is a comment
+
+    """
+
+    def __init__(self, text, **kwargs):
+        super(Comment, self).__init__(**kwargs)
+        self.text = text
+
+    def __repr__(self):
+        return "Comment(%r, %r)" % (self.text, (self.lineno, self.pos))
+
+class Expression(Node):
+    """defines an inline expression.
+
+    ${x+y}
+
+    """
+
+    def __init__(self, text, escapes, **kwargs):
+        super(Expression, self).__init__(**kwargs)
+        self.text = text
+        self.escapes = escapes
+        self.escapes_code = ast.ArgumentList(escapes, **self.exception_kwargs)
+        self.code = ast.PythonCode(text, **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return []
+
+    def undeclared_identifiers(self):
+        # TODO: make the "filter" shortcut list configurable at parse/gen time
+        return self.code.undeclared_identifiers.union(
+                self.escapes_code.undeclared_identifiers.difference(
+                    set(filters.DEFAULT_ESCAPES.keys())
+                )
+            ).difference(self.code.declared_identifiers)
+
+    def __repr__(self):
+        return "Expression(%r, %r, %r)" % (
+            self.text,
+            self.escapes_code.args,
+            (self.lineno, self.pos)
+        )
+
+class _TagMeta(type):
+    """metaclass to allow Tag to produce a subclass according to
+    its keyword"""
+
+    _classmap = {}
+
+    def __init__(cls, clsname, bases, dict):
+        if cls.__keyword__ is not None:
+            cls._classmap[cls.__keyword__] = cls
+            super(_TagMeta, cls).__init__(clsname, bases, dict)
+
+    def __call__(cls, keyword, attributes, **kwargs):
+        if ":" in keyword:
+            ns, defname = keyword.split(':')
+            return type.__call__(CallNamespaceTag, ns, defname,
+                                        attributes, **kwargs)
+
+        try:
+            cls = _TagMeta._classmap[keyword]
+        except KeyError:
+            raise exceptions.CompileException(
+                "No such tag: '%s'" % keyword,
+                source=kwargs['source'],
+                lineno=kwargs['lineno'],
+                pos=kwargs['pos'],
+                filename=kwargs['filename']
+            )
+        return type.__call__(cls, keyword, attributes, **kwargs)
+
+class Tag(Node, metaclass=_TagMeta):
+    """abstract base class for tags.
+
+    <%sometag/>
+
+    <%someothertag>
+        stuff
+    </%someothertag>
+
+    """
+    __keyword__ = None
+
+    def __init__(self, keyword, attributes, expressions,
+                        nonexpressions, required, **kwargs):
+        """construct a new Tag instance.
+
+        this constructor not called directly, and is only called
+        by subclasses.
+
+        :param keyword: the tag keyword
+
+        :param attributes: raw dictionary of attribute key/value pairs
+
+        :param expressions: a set of identifiers that are legal attributes,
+         which can also contain embedded expressions
+
+        :param nonexpressions: a set of identifiers that are legal
+         attributes, which cannot contain embedded expressions
+
+        :param \**kwargs:
+         other arguments passed to the Node superclass (lineno, pos)
+
+        """
+        super(Tag, self).__init__(**kwargs)
+        self.keyword = keyword
+        self.attributes = attributes
+        self._parse_attributes(expressions, nonexpressions)
+        missing = [r for r in required if r not in self.parsed_attributes]
+        if len(missing):
+            raise exceptions.CompileException(
+                "Missing attribute(s): %s" %
+                    ",".join([repr(m) for m in missing]),
+                **self.exception_kwargs)
+        self.parent = None
+        self.nodes = []
+
+    def is_root(self):
+        return self.parent is None
+
+    def get_children(self):
+        return self.nodes
+
+    def _parse_attributes(self, expressions, nonexpressions):
+        undeclared_identifiers = set()
+        self.parsed_attributes = {}
+        for key in self.attributes:
+            if key in expressions:
+                expr = []
+                for x in re.compile(r'(\${.+?})',
+                                    re.S).split(self.attributes[key]):
+                    m = re.compile(r'^\${(.+?)}$', re.S).match(x)
+                    if m:
+                        code = ast.PythonCode(m.group(1).rstrip(),
+                                **self.exception_kwargs)
+                        # we aren't discarding "declared_identifiers" here,
+                        # which we do so that list comprehension-declared
+                        # variables aren't counted.   As yet can't find a
+                        # condition that requires it here.
+                        undeclared_identifiers = \
+                            undeclared_identifiers.union(
+                                    code.undeclared_identifiers)
+                        expr.append('(%s)' % m.group(1))
+                    else:
+                        if x:
+                            expr.append(repr(x))
+                self.parsed_attributes[key] = " + ".join(expr) or repr('')
+            elif key in nonexpressions:
+                if re.search(r'\${.+?}', self.attributes[key]):
+                    raise exceptions.CompileException(
+                           "Attibute '%s' in tag '%s' does not allow embedded "
+                           "expressions"  % (key, self.keyword),
+                           **self.exception_kwargs)
+                self.parsed_attributes[key] = repr(self.attributes[key])
+            else:
+                raise exceptions.CompileException(
+                                    "Invalid attribute for tag '%s': '%s'" %
+                                    (self.keyword, key),
+                                    **self.exception_kwargs)
+        self.expression_undeclared_identifiers = undeclared_identifiers
+
+    def declared_identifiers(self):
+        return []
+
+    def undeclared_identifiers(self):
+        return self.expression_undeclared_identifiers
+
+    def __repr__(self):
+        return "%s(%r, %s, %r, %r)" % (self.__class__.__name__,
+                                    self.keyword,
+                                    util.sorted_dict_repr(self.attributes),
+                                    (self.lineno, self.pos),
+                                    self.nodes
+                                )
+
+class IncludeTag(Tag):
+    __keyword__ = 'include'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(IncludeTag, self).__init__(
+                                    keyword,
+                                    attributes,
+                                    ('file', 'import', 'args'),
+                                    (), ('file',), **kwargs)
+        self.page_args = ast.PythonCode(
+                                "__DUMMY(%s)" % attributes.get('args', ''),
+                                 **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return []
+
+    def undeclared_identifiers(self):
+        identifiers = self.page_args.undeclared_identifiers.\
+                            difference(set(["__DUMMY"])).\
+                            difference(self.page_args.declared_identifiers)
+        return identifiers.union(super(IncludeTag, self).
+                                    undeclared_identifiers())
+
+class NamespaceTag(Tag):
+    __keyword__ = 'namespace'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(NamespaceTag, self).__init__(
+                                        keyword, attributes,
+                                        ('file',),
+                                        ('name','inheritable',
+                                        'import','module'),
+                                        (), **kwargs)
+
+        self.name = attributes.get('name', '__anon_%s' % hex(abs(id(self))))
+        if not 'name' in attributes and not 'import' in attributes:
+            raise exceptions.CompileException(
+                "'name' and/or 'import' attributes are required "
+                "for <%namespace>",
+                **self.exception_kwargs)
+        if 'file' in attributes and 'module' in attributes:
+            raise exceptions.CompileException(
+                "<%namespace> may only have one of 'file' or 'module'",
+                **self.exception_kwargs
+            )
+
+    def declared_identifiers(self):
+        return []
+
+class TextTag(Tag):
+    __keyword__ = 'text'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(TextTag, self).__init__(
+                                    keyword,
+                                    attributes, (),
+                                    ('filter'), (), **kwargs)
+        self.filter_args = ast.ArgumentList(
+                                    attributes.get('filter', ''),
+                                    **self.exception_kwargs)
+
+    def undeclared_identifiers(self):
+        return self.filter_args.\
+                            undeclared_identifiers.\
+                            difference(list(filters.DEFAULT_ESCAPES.keys())).union(
+                        self.expression_undeclared_identifiers
+                    )
+
+class DefTag(Tag):
+    __keyword__ = 'def'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        expressions = ['buffered', 'cached'] + [
+                c for c in attributes if c.startswith('cache_')]
+
+
+        super(DefTag, self).__init__(
+                keyword,
+                attributes,
+                expressions,
+                ('name', 'filter', 'decorator'),
+                ('name',),
+                **kwargs)
+        name = attributes['name']
+        if re.match(r'^[\w_]+$', name):
+            raise exceptions.CompileException(
+                                "Missing parenthesis in %def",
+                                **self.exception_kwargs)
+        self.function_decl = ast.FunctionDecl("def " + name + ":pass",
+                                                    **self.exception_kwargs)
+        self.name = self.function_decl.funcname
+        self.decorator = attributes.get('decorator', '')
+        self.filter_args = ast.ArgumentList(
+                                attributes.get('filter', ''),
+                                **self.exception_kwargs)
+
+    is_anonymous = False
+    is_block = False
+
+    @property
+    def funcname(self):
+        return self.function_decl.funcname
+
+    def get_argument_expressions(self, **kw):
+        return self.function_decl.get_argument_expressions(**kw)
+
+    def declared_identifiers(self):
+        return self.function_decl.argnames
+
+    def undeclared_identifiers(self):
+        res = []
+        for c in self.function_decl.defaults:
+            res += list(ast.PythonCode(c, **self.exception_kwargs).
+                                    undeclared_identifiers)
+        return set(res).union(
+            self.filter_args.\
+                            undeclared_identifiers.\
+                            difference(list(filters.DEFAULT_ESCAPES.keys()))
+        ).union(
+            self.expression_undeclared_identifiers
+        ).difference(
+            self.function_decl.argnames
+        )
+
+class BlockTag(Tag):
+    __keyword__ = 'block'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        expressions = ['buffered', 'cached', 'args'] + [
+                 c for c in attributes if c.startswith('cache_')]
+
+        super(BlockTag, self).__init__(
+                keyword,
+                attributes,
+                expressions,
+                ('name','filter', 'decorator'),
+                (),
+                **kwargs)
+        name = attributes.get('name')
+        if name and not re.match(r'^[\w_]+$',name):
+            raise exceptions.CompileException(
+                               "%block may not specify an argument signature",
+                               **self.exception_kwargs)
+        if not name and attributes.get('args', None):
+            raise exceptions.CompileException(
+                                "Only named %blocks may specify args",
+                                **self.exception_kwargs
+                                )
+        self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
+                                            **self.exception_kwargs)
+
+        self.name = name
+        self.decorator = attributes.get('decorator', '')
+        self.filter_args = ast.ArgumentList(
+                                attributes.get('filter', ''),
+                                **self.exception_kwargs)
+
+
+    is_block = True
+
+    @property
+    def is_anonymous(self):
+        return self.name is None
+
+    @property
+    def funcname(self):
+        return self.name or "__M_anon_%d" % (self.lineno, )
+
+    def get_argument_expressions(self, **kw):
+        return self.body_decl.get_argument_expressions(**kw)
+
+    def declared_identifiers(self):
+        return self.body_decl.argnames
+
+    def undeclared_identifiers(self):
+        return (self.filter_args.\
+                            undeclared_identifiers.\
+                            difference(list(filters.DEFAULT_ESCAPES.keys()))
+                ).union(self.expression_undeclared_identifiers)
+
+
+
+class CallTag(Tag):
+    __keyword__ = 'call'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(CallTag, self).__init__(keyword, attributes,
+                                    ('args'), ('expr',), ('expr',), **kwargs)
+        self.expression = attributes['expr']
+        self.code = ast.PythonCode(self.expression, **self.exception_kwargs)
+        self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
+                                            **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return self.code.declared_identifiers.union(self.body_decl.argnames)
+
+    def undeclared_identifiers(self):
+        return self.code.undeclared_identifiers.\
+                    difference(self.code.declared_identifiers)
+
+class CallNamespaceTag(Tag):
+
+    def __init__(self, namespace, defname, attributes, **kwargs):
+        super(CallNamespaceTag, self).__init__(
+                    namespace + ":" + defname,
+                    attributes,
+                    tuple(attributes.keys()) + ('args', ),
+                    (),
+                    (),
+                    **kwargs)
+
+        self.expression = "%s.%s(%s)" % (
+                                namespace,
+                                defname,
+                                ",".join(["%s=%s" % (k, v) for k, v in
+                                            self.parsed_attributes.items()
+                                            if k != 'args'])
+                            )
+        self.code = ast.PythonCode(self.expression, **self.exception_kwargs)
+        self.body_decl = ast.FunctionArgs(
+                                    attributes.get('args', ''),
+                                    **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return self.code.declared_identifiers.union(self.body_decl.argnames)
+
+    def undeclared_identifiers(self):
+        return self.code.undeclared_identifiers.\
+                    difference(self.code.declared_identifiers)
+
+class InheritTag(Tag):
+    __keyword__ = 'inherit'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(InheritTag, self).__init__(
+                                keyword, attributes,
+                                ('file',), (), ('file',), **kwargs)
+
+class PageTag(Tag):
+    __keyword__ = 'page'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        expressions =   ['cached', 'args', 'expression_filter', 'enable_loop'] + [
+                    c for c in attributes if c.startswith('cache_')]
+
+        super(PageTag, self).__init__(
+                keyword,
+                attributes,
+                expressions,
+                (),
+                (),
+                **kwargs)
+        self.body_decl = ast.FunctionArgs(attributes.get('args', ''),
+                                            **self.exception_kwargs)
+        self.filter_args = ast.ArgumentList(
+                                attributes.get('expression_filter', ''),
+                                **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return self.body_decl.argnames
+
+
diff --git a/lib3/Mako-0.7.3/mako/pygen.py b/lib3/Mako-0.7.3/mako/pygen.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/pygen.py
@@ -0,0 +1,283 @@
+# mako/pygen.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""utilities for generating and formatting literal Python code."""
+
+import re, string
+from io import StringIO
+from mako import exceptions
+
+class PythonPrinter(object):
+    def __init__(self, stream):
+        # indentation counter
+        self.indent = 0
+
+        # a stack storing information about why we incremented
+        # the indentation counter, to help us determine if we
+        # should decrement it
+        self.indent_detail = []
+
+        # the string of whitespace multiplied by the indent
+        # counter to produce a line
+        self.indentstring = "    "
+
+        # the stream we are writing to
+        self.stream = stream
+
+        # a list of lines that represents a buffered "block" of code,
+        # which can be later printed relative to an indent level
+        self.line_buffer = []
+
+        self.in_indent_lines = False
+
+        self._reset_multi_line_flags()
+
+    def write(self, text):
+        self.stream.write(text)
+
+    def write_indented_block(self, block):
+        """print a line or lines of python which already contain indentation.
+
+        The indentation of the total block of lines will be adjusted to that of
+        the current indent level."""
+        self.in_indent_lines = False
+        for l in re.split(r'\r?\n', block):
+            self.line_buffer.append(l)
+
+    def writelines(self, *lines):
+        """print a series of lines of python."""
+        for line in lines:
+            self.writeline(line)
+
+    def writeline(self, line):
+        """print a line of python, indenting it according to the current
+        indent level.
+
+        this also adjusts the indentation counter according to the
+        content of the line.
+
+        """
+
+        if not self.in_indent_lines:
+            self._flush_adjusted_lines()
+            self.in_indent_lines = True
+
+        if (line is None or
+            re.match(r"^\s*#",line) or
+            re.match(r"^\s*$", line)
+            ):
+            hastext = False
+        else:
+            hastext = True
+
+        is_comment = line and len(line) and line[0] == '#'
+
+        # see if this line should decrease the indentation level
+        if (not is_comment and
+            (not hastext or self._is_unindentor(line))
+            ):
+
+            if self.indent > 0:
+                self.indent -=1
+                # if the indent_detail stack is empty, the user
+                # probably put extra closures - the resulting
+                # module wont compile.
+                if len(self.indent_detail) == 0:
+                    raise exceptions.SyntaxException(
+                                    "Too many whitespace closures")
+                self.indent_detail.pop()
+
+        if line is None:
+            return
+
+        # write the line
+        self.stream.write(self._indent_line(line) + "\n")
+
+        # see if this line should increase the indentation level.
+        # note that a line can both decrase (before printing) and
+        # then increase (after printing) the indentation level.
+
+        if re.search(r":[ \t]*(?:#.*)?$", line):
+            # increment indentation count, and also
+            # keep track of what the keyword was that indented us,
+            # if it is a python compound statement keyword
+            # where we might have to look for an "unindent" keyword
+            match = re.match(r"^\s*(if|try|elif|while|for|with)", line)
+            if match:
+                # its a "compound" keyword, so we will check for "unindentors"
+                indentor = match.group(1)
+                self.indent +=1
+                self.indent_detail.append(indentor)
+            else:
+                indentor = None
+                # its not a "compound" keyword.  but lets also
+                # test for valid Python keywords that might be indenting us,
+                # else assume its a non-indenting line
+                m2 = re.match(r"^\s*(def|class|else|elif|except|finally)",
+                              line)
+                if m2:
+                    self.indent += 1
+                    self.indent_detail.append(indentor)
+
+    def close(self):
+        """close this printer, flushing any remaining lines."""
+        self._flush_adjusted_lines()
+
+    def _is_unindentor(self, line):
+        """return true if the given line is an 'unindentor',
+        relative to the last 'indent' event received.
+
+        """
+
+        # no indentation detail has been pushed on; return False
+        if len(self.indent_detail) == 0:
+            return False
+
+        indentor = self.indent_detail[-1]
+
+        # the last indent keyword we grabbed is not a
+        # compound statement keyword; return False
+        if indentor is None:
+            return False
+
+        # if the current line doesnt have one of the "unindentor" keywords,
+        # return False
+        match = re.match(r"^\s*(else|elif|except|finally).*\:", line)
+        if not match:
+            return False
+
+        # whitespace matches up, we have a compound indentor,
+        # and this line has an unindentor, this
+        # is probably good enough
+        return True
+
+        # should we decide that its not good enough, heres
+        # more stuff to check.
+        #keyword = match.group(1)
+
+        # match the original indent keyword
+        #for crit in [
+        #   (r'if|elif', r'else|elif'),
+        #   (r'try', r'except|finally|else'),
+        #   (r'while|for', r'else'),
+        #]:
+        #   if re.match(crit[0], indentor) and re.match(crit[1], keyword):
+        #        return True
+
+        #return False
+
+    def _indent_line(self, line, stripspace=''):
+        """indent the given line according to the current indent level.
+
+        stripspace is a string of space that will be truncated from the
+        start of the line before indenting."""
+
+        return re.sub(r"^%s" % stripspace, self.indentstring
+                      * self.indent, line)
+
+    def _reset_multi_line_flags(self):
+        """reset the flags which would indicate we are in a backslashed
+        or triple-quoted section."""
+
+        self.backslashed, self.triplequoted = False, False
+
+    def _in_multi_line(self, line):
+        """return true if the given line is part of a multi-line block,
+        via backslash or triple-quote."""
+
+        # we are only looking for explicitly joined lines here, not
+        # implicit ones (i.e. brackets, braces etc.).  this is just to
+        # guard against the possibility of modifying the space inside of
+        # a literal multiline string with unfortunately placed
+        # whitespace
+
+        current_state = (self.backslashed or self.triplequoted)
+
+        if re.search(r"\\$", line):
+            self.backslashed = True
+        else:
+            self.backslashed = False
+
+        triples = len(re.findall(r"\"\"\"|\'\'\'", line))
+        if triples == 1 or triples % 2 != 0:
+            self.triplequoted = not self.triplequoted
+
+        return current_state
+
+    def _flush_adjusted_lines(self):
+        stripspace = None
+        self._reset_multi_line_flags()
+
+        for entry in self.line_buffer:
+            if self._in_multi_line(entry):
+                self.stream.write(entry + "\n")
+            else:
+                entry = entry.expandtabs()
+                if stripspace is None and re.search(r"^[ \t]*[^# \t]", entry):
+                    stripspace = re.match(r"^([ \t]*)", entry).group(1)
+                self.stream.write(self._indent_line(entry, stripspace) + "\n")
+
+        self.line_buffer = []
+        self._reset_multi_line_flags()
+
+
+def adjust_whitespace(text):
+    """remove the left-whitespace margin of a block of Python code."""
+
+    state = [False, False]
+    (backslashed, triplequoted) = (0, 1)
+
+    def in_multi_line(line):
+        start_state = (state[backslashed] or state[triplequoted])
+
+        if re.search(r"\\$", line):
+            state[backslashed] = True
+        else:
+            state[backslashed] = False
+
+        def match(reg, t):
+            m = re.match(reg, t)
+            if m:
+                return m, t[len(m.group(0)):]
+            else:
+                return None, t
+
+        while line:
+            if state[triplequoted]:
+                m, line = match(r"%s" % state[triplequoted], line)
+                if m:
+                    state[triplequoted] = False
+                else:
+                    m, line = match(r".*?(?=%s|$)" % state[triplequoted], line)
+            else:
+                m, line = match(r'#', line)
+                if m:
+                    return start_state
+
+                m, line = match(r"\"\"\"|\'\'\'", line)
+                if m:
+                    state[triplequoted] = m.group(0)
+                    continue
+
+                m, line = match(r".*?(?=\"\"\"|\'\'\'|#|$)", line)
+
+        return start_state
+
+    def _indent_line(line, stripspace = ''):
+        return re.sub(r"^%s" % stripspace, '', line)
+
+    lines = []
+    stripspace = None
+
+    for line in re.split(r'\r?\n', text):
+        if in_multi_line(line):
+            lines.append(line)
+        else:
+            line = line.expandtabs()
+            if stripspace is None and re.search(r"^[ \t]*[^# \t]", line):
+                stripspace = re.match(r"^([ \t]*)", line).group(1)
+            lines.append(_indent_line(line, stripspace))
+    return "\n".join(lines)
diff --git a/lib3/Mako-0.7.3/mako/pyparser.py b/lib3/Mako-0.7.3/mako/pyparser.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/pyparser.py
@@ -0,0 +1,551 @@
+# mako/pyparser.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""Handles parsing of Python code.
+
+Parsing to AST is done via _ast on Python > 2.5, otherwise the compiler
+module is used.
+"""
+
+from io import StringIO
+from mako import exceptions, util
+import operator
+
+if util.py3k:
+    # words that cannot be assigned to (notably
+    # smaller than the total keys in __builtins__)
+    reserved = set(['True', 'False', 'None', 'print'])
+
+    # the "id" attribute on a function node
+    arg_id = operator.attrgetter('arg')
+else:
+    # words that cannot be assigned to (notably
+    # smaller than the total keys in __builtins__)
+    reserved = set(['True', 'False', 'None'])
+
+    # the "id" attribute on a function node
+    arg_id = operator.attrgetter('id')
+
+
+try:
+    import _ast
+    util.restore__ast(_ast)
+    from . import _ast_util
+except ImportError:
+    _ast = None
+    from compiler import parse as compiler_parse
+    from compiler import visitor
+
+
+def parse(code, mode='exec', **exception_kwargs):
+    """Parse an expression into AST"""
+
+
+    try:
+        if _ast:
+            return _ast_util.parse(code, '<unknown>', mode)
+        else:
+            if isinstance(code, str):
+                code = code.encode('ascii', 'backslashreplace')
+            return compiler_parse(code, mode)
+    except Exception as e:
+        raise exceptions.SyntaxException(
+                    "(%s) %s (%r)" % (
+                        e.__class__.__name__,
+                        e,
+                        code[0:50]
+                    ), **exception_kwargs)
+
+
+if _ast:
+    class FindIdentifiers(_ast_util.NodeVisitor):
+
+        def __init__(self, listener, **exception_kwargs):
+            self.in_function = False
+            self.in_assign_targets = False
+            self.local_ident_stack = set()
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+
+        def _add_declared(self, name):
+            if not self.in_function:
+                self.listener.declared_identifiers.add(name)
+            else:
+                self.local_ident_stack.add(name)
+
+        def visit_ClassDef(self, node):
+            self._add_declared(node.name)
+
+        def visit_Assign(self, node):
+
+            # flip around the visiting of Assign so the expression gets
+            # evaluated first, in the case of a clause like "x=x+5" (x
+            # is undeclared)
+
+            self.visit(node.value)
+            in_a = self.in_assign_targets
+            self.in_assign_targets = True
+            for n in node.targets:
+                self.visit(n)
+            self.in_assign_targets = in_a
+
+        if util.py3k:
+
+            # ExceptHandler is in Python 2, but this block only works in
+            # Python 3 (and is required there)
+
+            def visit_ExceptHandler(self, node):
+                if node.name is not None:
+                    self._add_declared(node.name)
+                if node.type is not None:
+                    self.listener.undeclared_identifiers.add(node.type.id)
+                for statement in node.body:
+                    self.visit(statement)
+
+        def visit_Lambda(self, node, *args):
+            self._visit_function(node, True)
+
+        def visit_FunctionDef(self, node):
+            self._add_declared(node.name)
+            self._visit_function(node, False)
+
+        def _expand_tuples(self, args):
+            for arg in args:
+                if isinstance(arg, _ast.Tuple):
+                    for n in arg.elts:
+                        yield n
+                else:
+                    yield arg
+
+        def _visit_function(self, node, islambda):
+
+            # push function state onto stack.  dont log any more
+            # identifiers as "declared" until outside of the function,
+            # but keep logging identifiers as "undeclared". track
+            # argument names in each function header so they arent
+            # counted as "undeclared"
+
+            inf = self.in_function
+            self.in_function = True
+
+            local_ident_stack = self.local_ident_stack
+            self.local_ident_stack = local_ident_stack.union([
+                arg_id(arg) for arg in self._expand_tuples(node.args.args)
+            ])
+            if islambda:
+                self.visit(node.body)
+            else:
+                for n in node.body:
+                    self.visit(n)
+            self.in_function = inf
+            self.local_ident_stack = local_ident_stack
+
+        def visit_For(self, node):
+
+            # flip around visit
+
+            self.visit(node.iter)
+            self.visit(node.target)
+            for statement in node.body:
+                self.visit(statement)
+            for statement in node.orelse:
+                self.visit(statement)
+
+        def visit_Name(self, node):
+            if isinstance(node.ctx, _ast.Store):
+                # this is eqiuvalent to visit_AssName in
+                # compiler
+                self._add_declared(node.id)
+            elif node.id not in reserved and node.id \
+                not in self.listener.declared_identifiers and node.id \
+                not in self.local_ident_stack:
+                self.listener.undeclared_identifiers.add(node.id)
+
+        def visit_Import(self, node):
+            for name in node.names:
+                if name.asname is not None:
+                    self._add_declared(name.asname)
+                else:
+                    self._add_declared(name.name.split('.')[0])
+
+        def visit_ImportFrom(self, node):
+            for name in node.names:
+                if name.asname is not None:
+                    self._add_declared(name.asname)
+                else:
+                    if name.name == '*':
+                        raise exceptions.CompileException(
+                          "'import *' is not supported, since all identifier "
+                          "names must be explicitly declared.  Please use the "
+                          "form 'from <modulename> import <name1>, <name2>, "
+                          "...' instead.", **self.exception_kwargs)
+                    self._add_declared(name.name)
+
+
+    class FindTuple(_ast_util.NodeVisitor):
+
+        def __init__(self, listener, code_factory, **exception_kwargs):
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+            self.code_factory = code_factory
+
+        def visit_Tuple(self, node):
+            for n in node.elts:
+                p = self.code_factory(n, **self.exception_kwargs)
+                self.listener.codeargs.append(p)
+                self.listener.args.append(ExpressionGenerator(n).value())
+                self.listener.declared_identifiers = \
+                    self.listener.declared_identifiers.union(
+                                                    p.declared_identifiers)
+                self.listener.undeclared_identifiers = \
+                    self.listener.undeclared_identifiers.union(
+                                                    p.undeclared_identifiers)
+
+
+    class ParseFunc(_ast_util.NodeVisitor):
+
+        def __init__(self, listener, **exception_kwargs):
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+
+        def visit_FunctionDef(self, node):
+            self.listener.funcname = node.name
+            argnames = [arg_id(arg) for arg in node.args.args]
+            if node.args.vararg:
+                argnames.append(node.args.vararg)
+            if node.args.kwarg:
+                argnames.append(node.args.kwarg)
+            self.listener.argnames = argnames
+            self.listener.defaults = node.args.defaults  # ast
+            self.listener.varargs = node.args.vararg
+            self.listener.kwargs = node.args.kwarg
+
+
+    class ExpressionGenerator(object):
+
+        def __init__(self, astnode):
+            self.generator = _ast_util.SourceGenerator(' ' * 4)
+            self.generator.visit(astnode)
+
+        def value(self):
+            return ''.join(self.generator.result)
+else:
+    class FindIdentifiers(object):
+
+        def __init__(self, listener, **exception_kwargs):
+            self.in_function = False
+            self.local_ident_stack = set()
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+
+        def _add_declared(self, name):
+            if not self.in_function:
+                self.listener.declared_identifiers.add(name)
+            else:
+                self.local_ident_stack.add(name)
+
+        def visitClass(self, node, *args):
+            self._add_declared(node.name)
+
+        def visitAssName(self, node, *args):
+            self._add_declared(node.name)
+
+        def visitAssign(self, node, *args):
+
+            # flip around the visiting of Assign so the expression gets
+            # evaluated first, in the case of a clause like "x=x+5" (x
+            # is undeclared)
+            self.visit(node.expr, *args)
+            for n in node.nodes:
+                self.visit(n, *args)
+
+        def visitLambda(self, node, *args):
+            self._visit_function(node, args)
+
+        def visitFunction(self, node, *args):
+            self._add_declared(node.name)
+            self._visit_function(node, args)
+
+        def _expand_tuples(self, args):
+            for arg in args:
+                if isinstance(arg, tuple):
+                    for n in arg:
+                        yield n
+                else:
+                    yield arg
+
+        def _visit_function(self, node, args):
+
+            # push function state onto stack.  dont log any more
+            # identifiers as "declared" until outside of the function,
+            # but keep logging identifiers as "undeclared". track
+            # argument names in each function header so they arent
+            # counted as "undeclared"
+
+            inf = self.in_function
+            self.in_function = True
+
+            local_ident_stack = self.local_ident_stack
+            self.local_ident_stack = local_ident_stack.union([
+                arg for arg in self._expand_tuples(node.argnames)
+            ])
+
+            for n in node.getChildNodes():
+                self.visit(n, *args)
+            self.in_function = inf
+            self.local_ident_stack = local_ident_stack
+
+        def visitFor(self, node, *args):
+
+            # flip around visit
+
+            self.visit(node.list, *args)
+            self.visit(node.assign, *args)
+            self.visit(node.body, *args)
+
+        def visitName(self, node, *args):
+            if node.name not in reserved and node.name \
+                not in self.listener.declared_identifiers and node.name \
+                not in self.local_ident_stack:
+                self.listener.undeclared_identifiers.add(node.name)
+
+        def visitImport(self, node, *args):
+            for mod, alias in node.names:
+                if alias is not None:
+                    self._add_declared(alias)
+                else:
+                    self._add_declared(mod.split('.')[0])
+
+        def visitFrom(self, node, *args):
+            for mod, alias in node.names:
+                if alias is not None:
+                    self._add_declared(alias)
+                else:
+                    if mod == '*':
+                        raise exceptions.CompileException(
+                        "'import *' is not supported, since all identifier "
+                        "names must be explicitly declared.  Please use the "
+                        "form 'from <modulename> import <name1>, <name2>, "
+                        "...' instead.", **self.exception_kwargs)
+                    self._add_declared(mod)
+
+        def visit(self, expr):
+            visitor.walk(expr, self)  # , walker=walker())
+
+
+    class FindTuple(object):
+
+        def __init__(self, listener, code_factory, **exception_kwargs):
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+            self.code_factory = code_factory
+
+        def visitTuple(self, node, *args):
+            for n in node.nodes:
+                p = self.code_factory(n, **self.exception_kwargs)
+                self.listener.codeargs.append(p)
+                self.listener.args.append(ExpressionGenerator(n).value())
+                self.listener.declared_identifiers = \
+                    self.listener.declared_identifiers.union(
+                                                      p.declared_identifiers)
+                self.listener.undeclared_identifiers = \
+                    self.listener.undeclared_identifiers.union(
+                                                      p.undeclared_identifiers)
+
+        def visit(self, expr):
+            visitor.walk(expr, self)  # , walker=walker())
+
+
+    class ParseFunc(object):
+
+        def __init__(self, listener, **exception_kwargs):
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+
+        def visitFunction(self, node, *args):
+            self.listener.funcname = node.name
+            self.listener.argnames = node.argnames
+            self.listener.defaults = node.defaults
+            self.listener.varargs = node.varargs
+            self.listener.kwargs = node.kwargs
+
+        def visit(self, expr):
+            visitor.walk(expr, self)
+
+
+    class ExpressionGenerator(object):
+
+        """given an AST node, generates an equivalent literal Python
+        expression."""
+
+        def __init__(self, astnode):
+            self.buf = StringIO()
+            visitor.walk(astnode, self)  # , walker=walker())
+
+        def value(self):
+            return self.buf.getvalue()
+
+        def operator(self, op, node, *args):
+            self.buf.write('(')
+            self.visit(node.left, *args)
+            self.buf.write(' %s ' % op)
+            self.visit(node.right, *args)
+            self.buf.write(')')
+
+        def booleanop(self, op, node, *args):
+            self.visit(node.nodes[0])
+            for n in node.nodes[1:]:
+                self.buf.write(' ' + op + ' ')
+                self.visit(n, *args)
+
+        def visitConst(self, node, *args):
+            self.buf.write(repr(node.value))
+
+        def visitAssName(self, node, *args):
+
+            # TODO: figure out OP_ASSIGN, other OP_s
+
+            self.buf.write(node.name)
+
+        def visitName(self, node, *args):
+            self.buf.write(node.name)
+
+        def visitMul(self, node, *args):
+            self.operator('*', node, *args)
+
+        def visitAnd(self, node, *args):
+            self.booleanop('and', node, *args)
+
+        def visitOr(self, node, *args):
+            self.booleanop('or', node, *args)
+
+        def visitBitand(self, node, *args):
+            self.booleanop('&', node, *args)
+
+        def visitBitor(self, node, *args):
+            self.booleanop('|', node, *args)
+
+        def visitBitxor(self, node, *args):
+            self.booleanop('^', node, *args)
+
+        def visitAdd(self, node, *args):
+            self.operator('+', node, *args)
+
+        def visitGetattr(self, node, *args):
+            self.visit(node.expr, *args)
+            self.buf.write('.%s' % node.attrname)
+
+        def visitSub(self, node, *args):
+            self.operator('-', node, *args)
+
+        def visitNot(self, node, *args):
+            self.buf.write('not ')
+            self.visit(node.expr)
+
+        def visitDiv(self, node, *args):
+            self.operator('/', node, *args)
+
+        def visitFloorDiv(self, node, *args):
+            self.operator('//', node, *args)
+
+        def visitSubscript(self, node, *args):
+            self.visit(node.expr)
+            self.buf.write('[')
+            [self.visit(x) for x in node.subs]
+            self.buf.write(']')
+
+        def visitUnarySub(self, node, *args):
+            self.buf.write('-')
+            self.visit(node.expr)
+
+        def visitUnaryAdd(self, node, *args):
+            self.buf.write('-')
+            self.visit(node.expr)
+
+        def visitSlice(self, node, *args):
+            self.visit(node.expr)
+            self.buf.write('[')
+            if node.lower is not None:
+                self.visit(node.lower)
+            self.buf.write(':')
+            if node.upper is not None:
+                self.visit(node.upper)
+            self.buf.write(']')
+
+        def visitDict(self, node):
+            self.buf.write('{')
+            c = node.getChildren()
+            for i in range(0, len(c), 2):
+                self.visit(c[i])
+                self.buf.write(': ')
+                self.visit(c[i + 1])
+                if i < len(c) - 2:
+                    self.buf.write(', ')
+            self.buf.write('}')
+
+        def visitTuple(self, node):
+            self.buf.write('(')
+            c = node.getChildren()
+            for i in range(0, len(c)):
+                self.visit(c[i])
+                if i < len(c) - 1:
+                    self.buf.write(', ')
+            self.buf.write(')')
+
+        def visitList(self, node):
+            self.buf.write('[')
+            c = node.getChildren()
+            for i in range(0, len(c)):
+                self.visit(c[i])
+                if i < len(c) - 1:
+                    self.buf.write(', ')
+            self.buf.write(']')
+
+        def visitListComp(self, node):
+            self.buf.write('[')
+            self.visit(node.expr)
+            self.buf.write(' ')
+            for n in node.quals:
+                self.visit(n)
+            self.buf.write(']')
+
+        def visitListCompFor(self, node):
+            self.buf.write(' for ')
+            self.visit(node.assign)
+            self.buf.write(' in ')
+            self.visit(node.list)
+            for n in node.ifs:
+                self.visit(n)
+
+        def visitListCompIf(self, node):
+            self.buf.write(' if ')
+            self.visit(node.test)
+
+        def visitCompare(self, node):
+            self.visit(node.expr)
+            for tup in node.ops:
+                self.buf.write(tup[0])
+                self.visit(tup[1])
+
+        def visitCallFunc(self, node, *args):
+            self.visit(node.node)
+            self.buf.write('(')
+            if len(node.args):
+                self.visit(node.args[0])
+                for a in node.args[1:]:
+                    self.buf.write(', ')
+                    self.visit(a)
+            self.buf.write(')')
+
+
+    class walker(visitor.ASTVisitor):
+
+        def dispatch(self, node, *args):
+            print('Node:', str(node))
+
+            # print "dir:", dir(node)
+
+            return visitor.ASTVisitor.dispatch(self, node, *args)
diff --git a/lib3/Mako-0.7.3/mako/runtime.py b/lib3/Mako-0.7.3/mako/runtime.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/runtime.py
@@ -0,0 +1,842 @@
+# mako/runtime.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""provides runtime services for templates, including Context,
+Namespace, and various helper functions."""
+
+from mako import exceptions, util
+import builtins, inspect, sys
+import collections
+
+
+class Context(object):
+    """Provides runtime namespace, output buffer, and various
+    callstacks for templates.
+
+    See :ref:`runtime_toplevel` for detail on the usage of
+    :class:`.Context`.
+
+     """
+
+    def __init__(self, buffer, **data):
+        self._buffer_stack = [buffer]
+
+        self._data = data
+
+        self._kwargs = data.copy()
+        self._with_template = None
+        self._outputting_as_unicode = None
+        self.namespaces = {}
+
+        # "capture" function which proxies to the
+        # generic "capture" function
+        self._data['capture'] = util.partial(capture, self)
+
+        # "caller" stack used by def calls with content
+        self.caller_stack = self._data['caller'] = CallerStack()
+
+    def _set_with_template(self, t):
+        self._with_template = t
+        illegal_names = t.reserved_names.intersection(self._data)
+        if illegal_names:
+            raise exceptions.NameConflictError(
+                "Reserved words passed to render(): %s" %
+                ", ".join(illegal_names))
+
+    @property
+    def lookup(self):
+        """Return the :class:`.TemplateLookup` associated
+        with this :class:`.Context`.
+
+        """
+        return self._with_template.lookup
+
+    @property
+    def kwargs(self):
+        """Return the dictionary of keyword arguments associated with this
+        :class:`.Context`.
+
+        """
+        return self._kwargs.copy()
+
+    def push_caller(self, caller):
+        """Push a ``caller`` callable onto the callstack for
+        this :class:`.Context`."""
+
+
+        self.caller_stack.append(caller)
+
+    def pop_caller(self):
+        """Pop a ``caller`` callable onto the callstack for this
+        :class:`.Context`."""
+
+        del self.caller_stack[-1]
+
+    def keys(self):
+        """Return a list of all names established in this :class:`.Context`."""
+
+        return list(self._data.keys())
+
+    def __getitem__(self, key):
+        if key in self._data:
+            return self._data[key]
+        else:
+            return builtins.__dict__[key]
+
+    def _push_writer(self):
+        """push a capturing buffer onto this Context and return
+        the new writer function."""
+
+        buf = util.FastEncodingBuffer()
+        self._buffer_stack.append(buf)
+        return buf.write
+
+    def _pop_buffer_and_writer(self):
+        """pop the most recent capturing buffer from this Context
+        and return the current writer after the pop.
+
+        """
+
+        buf = self._buffer_stack.pop()
+        return buf, self._buffer_stack[-1].write
+
+    def _push_buffer(self):
+        """push a capturing buffer onto this Context."""
+
+        self._push_writer()
+
+    def _pop_buffer(self):
+        """pop the most recent capturing buffer from this Context."""
+
+        return self._buffer_stack.pop()
+
+    def get(self, key, default=None):
+        """Return a value from this :class:`.Context`."""
+
+        return self._data.get(key,
+                builtins.__dict__.get(key, default)
+                )
+
+    def write(self, string):
+        """Write a string to this :class:`.Context` object's
+        underlying output buffer."""
+
+        self._buffer_stack[-1].write(string)
+
+    def writer(self):
+        """Return the current writer function."""
+
+        return self._buffer_stack[-1].write
+
+    def _copy(self):
+        c = Context.__new__(Context)
+        c._buffer_stack = self._buffer_stack
+        c._data = self._data.copy()
+        c._kwargs = self._kwargs
+        c._with_template = self._with_template
+        c._outputting_as_unicode = self._outputting_as_unicode
+        c.namespaces = self.namespaces
+        c.caller_stack = self.caller_stack
+        return c
+
+    def locals_(self, d):
+        """Create a new :class:`.Context` with a copy of this
+        :class:`.Context`'s current state, updated with the given dictionary."""
+
+        if len(d) == 0:
+            return self
+        c = self._copy()
+        c._data.update(d)
+        return c
+
+    def _clean_inheritance_tokens(self):
+        """create a new copy of this :class:`.Context`. with
+        tokens related to inheritance state removed."""
+
+        c = self._copy()
+        x = c._data
+        x.pop('self', None)
+        x.pop('parent', None)
+        x.pop('next', None)
+        return c
+
+class CallerStack(list):
+    def __init__(self):
+        self.nextcaller = None
+    def __bool__(self):
+        return self._get_caller() and True or False
+    def _get_caller(self):
+        # this method can be removed once
+        # codegen MAGIC_NUMBER moves past 7
+        return self[-1]
+    def __getattr__(self, key):
+        return getattr(self._get_caller(), key)
+    def _push_frame(self):
+        frame = self.nextcaller or None
+        self.append(frame)
+        self.nextcaller = None
+        return frame
+    def _pop_frame(self):
+        self.nextcaller = self.pop()
+
+
+class Undefined(object):
+    """Represents an undefined value in a template.
+
+    All template modules have a constant value
+    ``UNDEFINED`` present which is an instance of this
+    object.
+
+    """
+    def __str__(self):
+        raise NameError("Undefined")
+    def __bool__(self):
+        return False
+
+UNDEFINED = Undefined()
+
+class LoopStack(object):
+    """a stack for LoopContexts that implements the context manager protocol
+    to automatically pop off the top of the stack on context exit
+    """
+
+    def __init__(self):
+        self.stack = []
+
+    def _enter(self, iterable):
+        self._push(iterable)
+        return self._top
+
+    def _exit(self):
+        self._pop()
+        return self._top
+
+    @property
+    def _top(self):
+        if self.stack:
+            return self.stack[-1]
+        else:
+            return self
+
+    def _pop(self):
+        return self.stack.pop()
+
+    def _push(self, iterable):
+        new = LoopContext(iterable)
+        if self.stack:
+            new.parent = self.stack[-1]
+        return self.stack.append(new)
+
+    def __getattr__(self, key):
+        raise exceptions.RuntimeException("No loop context is established")
+
+    def __iter__(self):
+        return iter(self._top)
+
+
+class LoopContext(object):
+    """A magic loop variable.
+    Automatically accessible in any ``% for`` block.
+
+    See the section :ref:`loop_context` for usage
+    notes.
+
+    :attr:`parent` -> :class:`.LoopContext` or ``None``
+        The parent loop, if one exists.
+    :attr:`index` -> `int`
+        The 0-based iteration count.
+    :attr:`reverse_index` -> `int`
+        The number of iterations remaining.
+    :attr:`first` -> `bool`
+        ``True`` on the first iteration, ``False`` otherwise.
+    :attr:`last` -> `bool`
+        ``True`` on the last iteration, ``False`` otherwise.
+    :attr:`even` -> `bool`
+        ``True`` when ``index`` is even.
+    :attr:`odd` -> `bool`
+        ``True`` when ``index`` is odd.
+    """
+
+    def __init__(self, iterable):
+        self._iterable = iterable
+        self.index = 0
+        self.parent = None
+
+    def __iter__(self):
+        for i in self._iterable:
+            yield i
+            self.index += 1
+
+    @util.memoized_instancemethod
+    def __len__(self):
+        return len(self._iterable)
+
+    @property
+    def reverse_index(self):
+        return len(self) - self.index - 1
+
+    @property
+    def first(self):
+        return self.index == 0
+
+    @property
+    def last(self):
+        return self.index == len(self) - 1
+
+    @property
+    def even(self):
+        return not self.odd
+
+    @property
+    def odd(self):
+        return bool(self.index % 2)
+
+    def cycle(self, *values):
+        """Cycle through values as the loop progresses.
+        """
+        if not values:
+            raise ValueError("You must provide values to cycle through")
+        return values[self.index % len(values)]
+
+
+class _NSAttr(object):
+    def __init__(self, parent):
+        self.__parent = parent
+    def __getattr__(self, key):
+        ns = self.__parent
+        while ns:
+            if hasattr(ns.module, key):
+                return getattr(ns.module, key)
+            else:
+                ns = ns.inherits
+        raise AttributeError(key)
+
+class Namespace(object):
+    """Provides access to collections of rendering methods, which
+      can be local, from other templates, or from imported modules.
+
+      To access a particular rendering method referenced by a
+      :class:`.Namespace`, use plain attribute access:
+
+      .. sourcecode:: mako
+
+        ${some_namespace.foo(x, y, z)}
+
+      :class:`.Namespace` also contains several built-in attributes
+      described here.
+
+      """
+
+    def __init__(self, name, context,
+                            callables=None, inherits=None,
+                            populate_self=True, calling_uri=None):
+        self.name = name
+        self.context = context
+        self.inherits = inherits
+        if callables is not None:
+            self.callables = dict([(c.__name__, c) for c in callables])
+
+    callables = ()
+
+    module = None
+    """The Python module referenced by this :class:`.Namespace`.
+
+    If the namespace references a :class:`.Template`, then
+    this module is the equivalent of ``template.module``,
+    i.e. the generated module for the template.
+
+    """
+
+    template = None
+    """The :class:`.Template` object referenced by this
+        :class:`.Namespace`, if any.
+
+    """
+
+    context = None
+    """The :class:`.Context` object for this :class:`.Namespace`.
+
+    Namespaces are often created with copies of contexts that
+    contain slightly different data, particularly in inheritance
+    scenarios. Using the :class:`.Context` off of a :class:`.Namespace` one
+    can traverse an entire chain of templates that inherit from
+    one-another.
+
+    """
+
+    filename = None
+    """The path of the filesystem file used for this
+    :class:`.Namespace`'s module or template.
+
+    If this is a pure module-based
+    :class:`.Namespace`, this evaluates to ``module.__file__``. If a
+    template-based namespace, it evaluates to the original
+    template file location.
+
+    """
+
+    uri = None
+    """The URI for this :class:`.Namespace`'s template.
+
+    I.e. whatever was sent to :meth:`.TemplateLookup.get_template()`.
+
+    This is the equivalent of :attr:`.Template.uri`.
+
+    """
+
+    _templateuri = None
+
+    @util.memoized_property
+    def attr(self):
+        """Access module level attributes by name.
+
+        This accessor allows templates to supply "scalar"
+        attributes which are particularly handy in inheritance
+        relationships. See the example in
+        :ref:`inheritance_toplevel`.
+
+        """
+        return _NSAttr(self)
+
+    def get_namespace(self, uri):
+        """Return a :class:`.Namespace` corresponding to the given ``uri``.
+
+        If the given ``uri`` is a relative URI (i.e. it does not
+        contain a leading slash ``/``), the ``uri`` is adjusted to
+        be relative to the ``uri`` of the namespace itself. This
+        method is therefore mostly useful off of the built-in
+        ``local`` namespace, described in :ref:`namespace_local`.
+
+        In
+        most cases, a template wouldn't need this function, and
+        should instead use the ``<%namespace>`` tag to load
+        namespaces. However, since all ``<%namespace>`` tags are
+        evaluated before the body of a template ever runs,
+        this method can be used to locate namespaces using
+        expressions that were generated within the body code of
+        the template, or to conditionally use a particular
+        namespace.
+
+        """
+        key = (self, uri)
+        if key in self.context.namespaces:
+            return self.context.namespaces[key]
+        else:
+            ns = TemplateNamespace(uri, self.context._copy(),
+                                templateuri=uri,
+                                calling_uri=self._templateuri)
+            self.context.namespaces[key] = ns
+            return ns
+
+    def get_template(self, uri):
+        """Return a :class:`.Template` from the given ``uri``.
+
+        The ``uri`` resolution is relative to the ``uri`` of this :class:`.Namespace`
+        object's :class:`.Template`.
+
+        """
+        return _lookup_template(self.context, uri, self._templateuri)
+
+    def get_cached(self, key, **kwargs):
+        """Return a value from the :class:`.Cache` referenced by this
+        :class:`.Namespace` object's :class:`.Template`.
+
+        The advantage to this method versus direct access to the
+        :class:`.Cache` is that the configuration parameters
+        declared in ``<%page>`` take effect here, thereby calling
+        up the same configured backend as that configured
+        by ``<%page>``.
+
+        """
+
+        return self.cache.get(key, **kwargs)
+
+    @property
+    def cache(self):
+        """Return the :class:`.Cache` object referenced
+        by this :class:`.Namespace` object's
+        :class:`.Template`.
+
+        """
+        return self.template.cache
+
+    def include_file(self, uri, **kwargs):
+        """Include a file at the given ``uri``."""
+
+        _include_file(self.context, uri, self._templateuri, **kwargs)
+
+    def _populate(self, d, l):
+        for ident in l:
+            if ident == '*':
+                for (k, v) in self._get_star():
+                    d[k] = v
+            else:
+                d[ident] = getattr(self, ident)
+
+    def _get_star(self):
+        if self.callables:
+            for key in self.callables:
+                yield (key, self.callables[key])
+
+    def __getattr__(self, key):
+        if key in self.callables:
+            val = self.callables[key]
+        elif self.inherits:
+            val = getattr(self.inherits, key)
+        else:
+            raise AttributeError(
+                    "Namespace '%s' has no member '%s'" %
+                    (self.name, key))
+        setattr(self, key, val)
+        return val
+
+class TemplateNamespace(Namespace):
+    """A :class:`.Namespace` specific to a :class:`.Template` instance."""
+
+    def __init__(self, name, context, template=None, templateuri=None,
+                            callables=None, inherits=None,
+                            populate_self=True, calling_uri=None):
+        self.name = name
+        self.context = context
+        self.inherits = inherits
+        if callables is not None:
+            self.callables = dict([(c.__name__, c) for c in callables])
+
+        if templateuri is not None:
+            self.template = _lookup_template(context, templateuri,
+                                                calling_uri)
+            self._templateuri = self.template.module._template_uri
+        elif template is not None:
+            self.template = template
+            self._templateuri = template.module._template_uri
+        else:
+            raise TypeError("'template' argument is required.")
+
+        if populate_self:
+            lclcallable, lclcontext = \
+                        _populate_self_namespace(context, self.template,
+                                                    self_ns=self)
+
+    @property
+    def module(self):
+        """The Python module referenced by this :class:`.Namespace`.
+
+        If the namespace references a :class:`.Template`, then
+        this module is the equivalent of ``template.module``,
+        i.e. the generated module for the template.
+
+        """
+        return self.template.module
+
+    @property
+    def filename(self):
+        """The path of the filesystem file used for this
+        :class:`.Namespace`'s module or template.
+        """
+        return self.template.filename
+
+    @property
+    def uri(self):
+        """The URI for this :class:`.Namespace`'s template.
+
+        I.e. whatever was sent to :meth:`.TemplateLookup.get_template()`.
+
+        This is the equivalent of :attr:`.Template.uri`.
+
+        """
+        return self.template.uri
+
+    def _get_star(self):
+        if self.callables:
+            for key in self.callables:
+                yield (key, self.callables[key])
+        def get(key):
+            callable_ = self.template._get_def_callable(key)
+            return util.partial(callable_, self.context)
+        for k in self.template.module._exports:
+            yield (k, get(k))
+
+    def __getattr__(self, key):
+        if key in self.callables:
+            val = self.callables[key]
+        elif self.template.has_def(key):
+            callable_ = self.template._get_def_callable(key)
+            val = util.partial(callable_, self.context)
+        elif self.inherits:
+            val = getattr(self.inherits, key)
+
+        else:
+            raise AttributeError(
+                    "Namespace '%s' has no member '%s'" %
+                    (self.name, key))
+        setattr(self, key, val)
+        return val
+
+class ModuleNamespace(Namespace):
+    """A :class:`.Namespace` specific to a Python module instance."""
+
+    def __init__(self, name, context, module,
+                            callables=None, inherits=None,
+                            populate_self=True, calling_uri=None):
+        self.name = name
+        self.context = context
+        self.inherits = inherits
+        if callables is not None:
+            self.callables = dict([(c.__name__, c) for c in callables])
+
+        mod = __import__(module)
+        for token in module.split('.')[1:]:
+            mod = getattr(mod, token)
+        self.module = mod
+
+    @property
+    def filename(self):
+        """The path of the filesystem file used for this
+        :class:`.Namespace`'s module or template.
+        """
+        return self.module.__file__
+
+    def _get_star(self):
+        if self.callables:
+            for key in self.callables:
+                yield (key, self.callables[key])
+        def get(key):
+            callable_ = getattr(self.module, key)
+            return util.partial(callable_, self.context)
+        for k in dir(self.module):
+            if k[0] != '_':
+                yield (k, get(k))
+
+    def __getattr__(self, key):
+        if key in self.callables:
+            val = self.callables[key]
+        elif hasattr(self.module, key):
+            callable_ = getattr(self.module, key)
+            val = util.partial(callable_, self.context)
+        elif self.inherits:
+            val = getattr(self.inherits, key)
+        else:
+            raise AttributeError(
+                    "Namespace '%s' has no member '%s'" %
+                    (self.name, key))
+        setattr(self, key, val)
+        return val
+
+def supports_caller(func):
+    """Apply a caller_stack compatibility decorator to a plain
+    Python function.
+
+    See the example in :ref:`namespaces_python_modules`.
+
+    """
+
+    def wrap_stackframe(context,  *args, **kwargs):
+        context.caller_stack._push_frame()
+        try:
+            return func(context, *args, **kwargs)
+        finally:
+            context.caller_stack._pop_frame()
+    return wrap_stackframe
+
+def capture(context, callable_, *args, **kwargs):
+    """Execute the given template def, capturing the output into
+    a buffer.
+
+    See the example in :ref:`namespaces_python_modules`.
+
+    """
+
+    if not isinstance(callable_, collections.Callable):
+        raise exceptions.RuntimeException(
+                           "capture() function expects a callable as "
+                           "its argument (i.e. capture(func, *args, **kwargs))"
+                        )
+    context._push_buffer()
+    try:
+        callable_(*args, **kwargs)
+    finally:
+        buf = context._pop_buffer()
+    return buf.getvalue()
+
+def _decorate_toplevel(fn):
+    def decorate_render(render_fn):
+        def go(context, *args, **kw):
+            def y(*args, **kw):
+                return render_fn(context, *args, **kw)
+            try:
+                y.__name__ = render_fn.__name__[7:]
+            except TypeError:
+                # < Python 2.4
+                pass
+            return fn(y)(context, *args, **kw)
+        return go
+    return decorate_render
+
+def _decorate_inline(context, fn):
+    def decorate_render(render_fn):
+        dec = fn(render_fn)
+        def go(*args, **kw):
+            return dec(context, *args, **kw)
+        return go
+    return decorate_render
+
+def _include_file(context, uri, calling_uri, **kwargs):
+    """locate the template from the given uri and include it in
+    the current output."""
+
+    template = _lookup_template(context, uri, calling_uri)
+    (callable_, ctx) = _populate_self_namespace(
+                                context._clean_inheritance_tokens(),
+                                template)
+    callable_(ctx, **_kwargs_for_include(callable_, context._data, **kwargs))
+
+def _inherit_from(context, uri, calling_uri):
+    """called by the _inherit method in template modules to set
+    up the inheritance chain at the start of a template's
+    execution."""
+
+    if uri is None:
+        return None
+    template = _lookup_template(context, uri, calling_uri)
+    self_ns = context['self']
+    ih = self_ns
+    while ih.inherits is not None:
+        ih = ih.inherits
+    lclcontext = context.locals_({'next':ih})
+    ih.inherits = TemplateNamespace("self:%s" % template.uri,
+                                lclcontext,
+                                template = template,
+                                populate_self=False)
+    context._data['parent'] = lclcontext._data['local'] = ih.inherits
+    callable_ = getattr(template.module, '_mako_inherit', None)
+    if callable_ is not None:
+        ret = callable_(template, lclcontext)
+        if ret:
+            return ret
+
+    gen_ns = getattr(template.module, '_mako_generate_namespaces', None)
+    if gen_ns is not None:
+        gen_ns(context)
+    return (template.callable_, lclcontext)
+
+def _lookup_template(context, uri, relativeto):
+    lookup = context._with_template.lookup
+    if lookup is None:
+        raise exceptions.TemplateLookupException(
+                            "Template '%s' has no TemplateLookup associated" %
+                            context._with_template.uri)
+    uri = lookup.adjust_uri(uri, relativeto)
+    try:
+        return lookup.get_template(uri)
+    except exceptions.TopLevelLookupException as e:
+        raise exceptions.TemplateLookupException(str(e))
+
+def _populate_self_namespace(context, template, self_ns=None):
+    if self_ns is None:
+        self_ns = TemplateNamespace('self:%s' % template.uri,
+                                context, template=template,
+                                populate_self=False)
+    context._data['self'] = context._data['local'] = self_ns
+    if hasattr(template.module, '_mako_inherit'):
+        ret = template.module._mako_inherit(template, context)
+        if ret:
+            return ret
+    return (template.callable_, context)
+
+def _render(template, callable_, args, data, as_unicode=False):
+    """create a Context and return the string
+    output of the given template and template callable."""
+
+    if as_unicode:
+        buf = util.FastEncodingBuffer(str=True)
+    elif template.bytestring_passthrough:
+        buf = util.StringIO()
+    else:
+        buf = util.FastEncodingBuffer(
+                        str=as_unicode,
+                        encoding=template.output_encoding,
+                        errors=template.encoding_errors)
+    context = Context(buf, **data)
+    context._outputting_as_unicode = as_unicode
+    context._set_with_template(template)
+
+    _render_context(template, callable_, context, *args,
+                            **_kwargs_for_callable(callable_, data))
+    return context._pop_buffer().getvalue()
+
+def _kwargs_for_callable(callable_, data):
+    argspec = util.inspect_func_args(callable_)
+    # for normal pages, **pageargs is usually present
+    if argspec[2]:
+        return data
+
+    # for rendering defs from the top level, figure out the args
+    namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
+    kwargs = {}
+    for arg in namedargs:
+        if arg != 'context' and arg in data and arg not in kwargs:
+            kwargs[arg] = data[arg]
+    return kwargs
+
+def _kwargs_for_include(callable_, data, **kwargs):
+    argspec = util.inspect_func_args(callable_)
+    namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
+    for arg in namedargs:
+        if arg != 'context' and arg in data and arg not in kwargs:
+            kwargs[arg] = data[arg]
+    return kwargs
+
+def _render_context(tmpl, callable_, context, *args, **kwargs):
+    import mako.template as template
+    # create polymorphic 'self' namespace for this
+    # template with possibly updated context
+    if not isinstance(tmpl, template.DefTemplate):
+        # if main render method, call from the base of the inheritance stack
+        (inherit, lclcontext) = _populate_self_namespace(context, tmpl)
+        _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
+    else:
+        # otherwise, call the actual rendering method specified
+        (inherit, lclcontext) = _populate_self_namespace(context, tmpl.parent)
+        _exec_template(callable_, context, args=args, kwargs=kwargs)
+
+def _exec_template(callable_, context, args=None, kwargs=None):
+    """execute a rendering callable given the callable, a
+    Context, and optional explicit arguments
+
+    the contextual Template will be located if it exists, and
+    the error handling options specified on that Template will
+    be interpreted here.
+    """
+    template = context._with_template
+    if template is not None and \
+            (template.format_exceptions or template.error_handler):
+        error = None
+        try:
+            callable_(context, *args, **kwargs)
+        except Exception as e:
+            _render_error(template, context, e)
+        except:
+            e = sys.exc_info()[0]
+            _render_error(template, context, e)
+    else:
+        callable_(context, *args, **kwargs)
+
+def _render_error(template, context, error):
+    if template.error_handler:
+        result = template.error_handler(context, error)
+        if not result:
+            raise error
+    else:
+        error_template = exceptions.html_error_template()
+        if context._outputting_as_unicode:
+            context._buffer_stack[:] = [util.FastEncodingBuffer(str=True)]
+        else:
+            context._buffer_stack[:] = [util.FastEncodingBuffer(
+                                            error_template.output_encoding,
+                                            error_template.encoding_errors)]
+
+        context._set_with_template(error_template)
+        error_template.render_context(context, error=error)
diff --git a/lib3/Mako-0.7.3/mako/template.py b/lib3/Mako-0.7.3/mako/template.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/template.py
@@ -0,0 +1,650 @@
+# mako/template.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""Provides the Template class, a facade for parsing, generating and executing
+template strings, as well as template runtime operations."""
+
+from mako.lexer import Lexer
+from mako import runtime, util, exceptions, codegen, cache
+import os, re, shutil, stat, sys, tempfile, types, weakref
+
+
+class Template(object):
+    """Represents a compiled template.
+
+    :class:`.Template` includes a reference to the original
+    template source (via the :attr:`.source` attribute)
+    as well as the source code of the
+    generated Python module (i.e. the :attr:`.code` attribute),
+    as well as a reference to an actual Python module.
+
+    :class:`.Template` is constructed using either a literal string
+    representing the template text, or a filename representing a filesystem
+    path to a source file.
+
+    :param text: textual template source.  This argument is mutually
+     exclusive versus the ``filename`` parameter.
+
+    :param filename: filename of the source template.  This argument is
+     mutually exclusive versus the ``text`` parameter.
+
+    :param buffer_filters: string list of filters to be applied
+     to the output of ``%def``\ s which are buffered, cached, or otherwise
+     filtered, after all filters
+     defined with the ``%def`` itself have been applied. Allows the
+     creation of default expression filters that let the output
+     of return-valued ``%def``\ s "opt out" of that filtering via
+     passing special attributes or objects.
+
+    :param bytestring_passthrough: When ``True``, and ``output_encoding`` is
+     set to ``None``, and :meth:`.Template.render` is used to render,
+     the `StringIO` or `cStringIO` buffer will be used instead of the
+     default "fast" buffer.   This allows raw bytestrings in the
+     output stream, such as in expressions, to pass straight
+     through to the buffer.  This flag is forced
+     to ``True`` if ``disable_unicode`` is also configured.
+
+     .. versionadded:: 0.4
+        Added to provide the same behavior as that of the previous series.
+
+    :param cache_args: Dictionary of cache configuration arguments that
+     will be passed to the :class:`.CacheImpl`.   See :ref:`caching_toplevel`.
+
+    :param cache_dir:
+
+     .. deprecated:: 0.6
+        Use the ``'dir'`` argument in the ``cache_args`` dictionary.
+        See :ref:`caching_toplevel`.
+
+    :param cache_enabled: Boolean flag which enables caching of this
+     template.  See :ref:`caching_toplevel`.
+
+    :param cache_impl: String name of a :class:`.CacheImpl` caching
+     implementation to use.   Defaults to ``'beaker'``.
+
+    :param cache_type:
+
+     .. deprecated:: 0.6
+        Use the ``'type'`` argument in the ``cache_args`` dictionary.
+        See :ref:`caching_toplevel`.
+
+    :param cache_url:
+
+     .. deprecated:: 0.6
+        Use the ``'url'`` argument in the ``cache_args`` dictionary.
+        See :ref:`caching_toplevel`.
+
+    :param default_filters: List of string filter names that will
+     be applied to all expressions.  See :ref:`filtering_default_filters`.
+
+    :param disable_unicode: Disables all awareness of Python Unicode
+     objects.  See :ref:`unicode_disabled`.
+
+    :param enable_loop: When ``True``, enable the ``loop`` context variable.
+     This can be set to ``False`` to support templates that may
+     be making usage of the name "``loop``".   Individual templates can
+     re-enable the "loop" context by placing the directive
+     ``enable_loop="True"`` inside the ``<%page>`` tag -- see
+     :ref:`migrating_loop`.
+
+    :param encoding_errors: Error parameter passed to ``encode()`` when
+     string encoding is performed. See :ref:`usage_unicode`.
+
+    :param error_handler: Python callable which is called whenever
+     compile or runtime exceptions occur. The callable is passed
+     the current context as well as the exception. If the
+     callable returns ``True``, the exception is considered to
+     be handled, else it is re-raised after the function
+     completes. Is used to provide custom error-rendering
+     functions.
+
+    :param format_exceptions: if ``True``, exceptions which occur during
+     the render phase of this template will be caught and
+     formatted into an HTML error page, which then becomes the
+     rendered result of the :meth:`.render` call. Otherwise,
+     runtime exceptions are propagated outwards.
+
+    :param imports: String list of Python statements, typically individual
+     "import" lines, which will be placed into the module level
+     preamble of all generated Python modules. See the example
+     in :ref:`filtering_default_filters`.
+
+    :param input_encoding: Encoding of the template's source code.  Can
+     be used in lieu of the coding comment. See
+     :ref:`usage_unicode` as well as :ref:`unicode_toplevel` for
+     details on source encoding.
+
+    :param lookup: a :class:`.TemplateLookup` instance that will be used
+     for all file lookups via the ``<%namespace>``,
+     ``<%include>``, and ``<%inherit>`` tags. See
+     :ref:`usage_templatelookup`.
+
+    :param module_directory: Filesystem location where generated
+     Python module files will be placed.
+
+    :param module_filename: Overrides the filename of the generated
+     Python module file. For advanced usage only.
+
+    :param module_writer: A callable which overrides how the Python
+     module is written entirely.  The callable is passed the
+     encoded source content of the module and the destination
+     path to be written to.   The default behavior of module writing
+     uses a tempfile in conjunction with a file move in order
+     to make the operation atomic.   So a user-defined module
+     writing function that mimics the default behavior would be:
+
+     .. sourcecode:: python
+
+         import tempfile
+         import os
+         import shutil
+
+         def module_writer(source, outputpath):
+             (dest, name) = \\
+                 tempfile.mkstemp(
+                     dir=os.path.dirname(outputpath)
+                 )
+
+             os.write(dest, source)
+             os.close(dest)
+             shutil.move(name, outputpath)
+
+         from mako.template import Template
+         mytemplate = Template(
+                         file="index.html",
+                         module_directory="/path/to/modules",
+                         module_writer=module_writer
+                     )
+
+     The function is provided for unusual configurations where
+     certain platform-specific permissions or other special
+     steps are needed.
+
+    :param output_encoding: The encoding to use when :meth:`.render`
+     is called.
+     See :ref:`usage_unicode` as well as :ref:`unicode_toplevel`.
+
+    :param preprocessor: Python callable which will be passed
+     the full template source before it is parsed. The return
+     result of the callable will be used as the template source
+     code.
+
+    :param strict_undefined: Replaces the automatic usage of
+     ``UNDEFINED`` for any undeclared variables not located in
+     the :class:`.Context` with an immediate raise of
+     ``NameError``. The advantage is immediate reporting of
+     missing variables which include the name.
+
+     .. versionadded:: 0.3.6
+
+    :param uri: string URI or other identifier for this template.
+     If not provided, the ``uri`` is generated from the filesystem
+     path, or from the in-memory identity of a non-file-based
+     template. The primary usage of the ``uri`` is to provide a key
+     within :class:`.TemplateLookup`, as well as to generate the
+     file path of the generated Python module file, if
+     ``module_directory`` is specified.
+
+    """
+
+    def __init__(self,
+                    text=None,
+                    filename=None,
+                    uri=None,
+                    format_exceptions=False,
+                    error_handler=None,
+                    lookup=None,
+                    output_encoding=None,
+                    encoding_errors='strict',
+                    module_directory=None,
+                    cache_args=None,
+                    cache_impl='beaker',
+                    cache_enabled=True,
+                    cache_type=None,
+                    cache_dir=None,
+                    cache_url=None,
+                    module_filename=None,
+                    input_encoding=None,
+                    disable_unicode=False,
+                    module_writer=None,
+                    bytestring_passthrough=False,
+                    default_filters=None,
+                    buffer_filters=(),
+                    strict_undefined=False,
+                    imports=None,
+                    enable_loop=True,
+                    preprocessor=None):
+        if uri:
+            self.module_id = re.sub(r'\W', "_", uri)
+            self.uri = uri
+        elif filename:
+            self.module_id = re.sub(r'\W', "_", filename)
+            drive, path = os.path.splitdrive(filename)
+            path = os.path.normpath(path).replace(os.path.sep, "/")
+            self.uri = path
+        else:
+            self.module_id = "memory:" + hex(id(self))
+            self.uri = self.module_id
+
+        u_norm = self.uri
+        if u_norm.startswith("/"):
+            u_norm = u_norm[1:]
+        u_norm = os.path.normpath(u_norm)
+        if u_norm.startswith(".."):
+            raise exceptions.TemplateLookupException(
+                    "Template uri \"%s\" is invalid - "
+                    "it cannot be relative outside "
+                    "of the root path." % self.uri)
+
+        self.input_encoding = input_encoding
+        self.output_encoding = output_encoding
+        self.encoding_errors = encoding_errors
+        self.disable_unicode = disable_unicode
+        self.bytestring_passthrough = bytestring_passthrough or disable_unicode
+        self.enable_loop = enable_loop
+        self.strict_undefined = strict_undefined
+        self.module_writer = module_writer
+
+        if util.py3k and disable_unicode:
+            raise exceptions.UnsupportedError(
+                                    "Mako for Python 3 does not "
+                                    "support disabling Unicode")
+        elif output_encoding and disable_unicode:
+            raise exceptions.UnsupportedError(
+                                    "output_encoding must be set to "
+                                    "None when disable_unicode is used.")
+        if default_filters is None:
+            if util.py3k or self.disable_unicode:
+                self.default_filters = ['str']
+            else:
+                self.default_filters = ['unicode']
+        else:
+            self.default_filters = default_filters
+        self.buffer_filters = buffer_filters
+
+        self.imports = imports
+        self.preprocessor = preprocessor
+
+        # if plain text, compile code in memory only
+        if text is not None:
+            (code, module) = _compile_text(self, text, filename)
+            self._code = code
+            self._source = text
+            ModuleInfo(module, None, self, filename, code, text)
+        elif filename is not None:
+            # if template filename and a module directory, load
+            # a filesystem-based module file, generating if needed
+            if module_filename is not None:
+                path = module_filename
+            elif module_directory is not None:
+                path = os.path.abspath(
+                        os.path.join(
+                            os.path.normpath(module_directory),
+                            u_norm + ".py"
+                            )
+                        )
+            else:
+                path = None
+            module = self._compile_from_file(path, filename)
+        else:
+            raise exceptions.RuntimeException(
+                                "Template requires text or filename")
+
+        self.module = module
+        self.filename = filename
+        self.callable_ = self.module.render_body
+        self.format_exceptions = format_exceptions
+        self.error_handler = error_handler
+        self.lookup = lookup
+
+        self.module_directory = module_directory
+
+        self._setup_cache_args(
+            cache_impl, cache_enabled, cache_args,
+            cache_type, cache_dir, cache_url
+        )
+
+    @util.memoized_property
+    def reserved_names(self):
+        if self.enable_loop:
+            return codegen.RESERVED_NAMES
+        else:
+            return codegen.RESERVED_NAMES.difference(['loop'])
+
+    def _setup_cache_args(self,
+                cache_impl, cache_enabled, cache_args,
+                cache_type, cache_dir, cache_url):
+        self.cache_impl = cache_impl
+        self.cache_enabled = cache_enabled
+        if cache_args:
+            self.cache_args = cache_args
+        else:
+            self.cache_args = {}
+
+        # transfer deprecated cache_* args
+        if cache_type:
+            self.cache_args['type'] = cache_type
+        if cache_dir:
+            self.cache_args['dir'] = cache_dir
+        if cache_url:
+            self.cache_args['url'] = cache_url
+
+    def _compile_from_file(self, path, filename):
+        if path is not None:
+            util.verify_directory(os.path.dirname(path))
+            filemtime = os.stat(filename)[stat.ST_MTIME]
+            if not os.path.exists(path) or \
+                        os.stat(path)[stat.ST_MTIME] < filemtime:
+                data = util.read_file(filename)
+                _compile_module_file(
+                            self,
+                            data,
+                            filename,
+                            path,
+                            self.module_writer)
+            module = util.load_module(self.module_id, path)
+            del sys.modules[self.module_id]
+            if module._magic_number != codegen.MAGIC_NUMBER:
+                data = util.read_file(filename)
+                _compile_module_file(
+                            self,
+                            data,
+                            filename,
+                            path,
+                            self.module_writer)
+                module = util.load_module(self.module_id, path)
+                del sys.modules[self.module_id]
+            ModuleInfo(module, path, self, filename, None, None)
+        else:
+            # template filename and no module directory, compile code
+            # in memory
+            data = util.read_file(filename)
+            code, module = _compile_text(
+                                self,
+                                data,
+                                filename)
+            self._source = None
+            self._code = code
+            ModuleInfo(module, None, self, filename, code, None)
+        return module
+
+    @property
+    def source(self):
+        """Return the template source code for this :class:`.Template`."""
+
+        return _get_module_info_from_callable(self.callable_).source
+
+    @property
+    def code(self):
+        """Return the module source code for this :class:`.Template`."""
+
+        return _get_module_info_from_callable(self.callable_).code
+
+    @util.memoized_property
+    def cache(self):
+        return cache.Cache(self)
+
+    @property
+    def cache_dir(self):
+        return self.cache_args['dir']
+    @property
+    def cache_url(self):
+        return self.cache_args['url']
+    @property
+    def cache_type(self):
+        return self.cache_args['type']
+
+    def render(self, *args, **data):
+        """Render the output of this template as a string.
+
+        If the template specifies an output encoding, the string
+        will be encoded accordingly, else the output is raw (raw
+        output uses `cStringIO` and can't handle multibyte
+        characters). A :class:`.Context` object is created corresponding
+        to the given data. Arguments that are explicitly declared
+        by this template's internal rendering method are also
+        pulled from the given ``*args``, ``**data`` members.
+
+        """
+        return runtime._render(self, self.callable_, args, data)
+
+    def render_unicode(self, *args, **data):
+        """Render the output of this template as a unicode object."""
+
+        return runtime._render(self,
+                                self.callable_,
+                                args,
+                                data,
+                                as_unicode=True)
+
+    def render_context(self, context, *args, **kwargs):
+        """Render this :class:`.Template` with the given context.
+
+        The data is written to the context's buffer.
+
+        """
+        if getattr(context, '_with_template', None) is None:
+            context._set_with_template(self)
+        runtime._render_context(self,
+                                self.callable_,
+                                context,
+                                *args,
+                                **kwargs)
+
+    def has_def(self, name):
+        return hasattr(self.module, "render_%s" % name)
+
+    def get_def(self, name):
+        """Return a def of this template as a :class:`.DefTemplate`."""
+
+        return DefTemplate(self, getattr(self.module, "render_%s" % name))
+
+    def _get_def_callable(self, name):
+        return getattr(self.module, "render_%s" % name)
+
+    @property
+    def last_modified(self):
+        return self.module._modified_time
+
+class ModuleTemplate(Template):
+    """A Template which is constructed given an existing Python module.
+
+        e.g.::
+
+        t = Template("this is a template")
+        f = file("mymodule.py", "w")
+        f.write(t.code)
+        f.close()
+
+        import mymodule
+
+        t = ModuleTemplate(mymodule)
+        print t.render()
+
+    """
+
+    def __init__(self, module,
+                        module_filename=None,
+                        template=None,
+                        template_filename=None,
+                        module_source=None,
+                        template_source=None,
+                        output_encoding=None,
+                        encoding_errors='strict',
+                        disable_unicode=False,
+                        bytestring_passthrough=False,
+                        format_exceptions=False,
+                        error_handler=None,
+                        lookup=None,
+                        cache_args=None,
+                        cache_impl='beaker',
+                        cache_enabled=True,
+                        cache_type=None,
+                        cache_dir=None,
+                        cache_url=None,
+    ):
+        self.module_id = re.sub(r'\W', "_", module._template_uri)
+        self.uri = module._template_uri
+        self.input_encoding = module._source_encoding
+        self.output_encoding = output_encoding
+        self.encoding_errors = encoding_errors
+        self.disable_unicode = disable_unicode
+        self.bytestring_passthrough = bytestring_passthrough or disable_unicode
+        self.enable_loop = module._enable_loop
+
+        if util.py3k and disable_unicode:
+            raise exceptions.UnsupportedError(
+                                    "Mako for Python 3 does not "
+                                    "support disabling Unicode")
+        elif output_encoding and disable_unicode:
+            raise exceptions.UnsupportedError(
+                                    "output_encoding must be set to "
+                                    "None when disable_unicode is used.")
+
+        self.module = module
+        self.filename = template_filename
+        ModuleInfo(module,
+                        module_filename,
+                        self,
+                        template_filename,
+                        module_source,
+                        template_source)
+
+        self.callable_ = self.module.render_body
+        self.format_exceptions = format_exceptions
+        self.error_handler = error_handler
+        self.lookup = lookup
+        self._setup_cache_args(
+            cache_impl, cache_enabled, cache_args,
+            cache_type, cache_dir, cache_url
+        )
+
+class DefTemplate(Template):
+    """A :class:`.Template` which represents a callable def in a parent
+    template."""
+
+    def __init__(self, parent, callable_):
+        self.parent = parent
+        self.callable_ = callable_
+        self.output_encoding = parent.output_encoding
+        self.module = parent.module
+        self.encoding_errors = parent.encoding_errors
+        self.format_exceptions = parent.format_exceptions
+        self.error_handler = parent.error_handler
+        self.enable_loop = parent.enable_loop
+        self.lookup = parent.lookup
+        self.bytestring_passthrough = parent.bytestring_passthrough
+
+    def get_def(self, name):
+        return self.parent.get_def(name)
+
+class ModuleInfo(object):
+    """Stores information about a module currently loaded into
+    memory, provides reverse lookups of template source, module
+    source code based on a module's identifier.
+
+     """
+    _modules = weakref.WeakValueDictionary()
+
+    def __init__(self,
+                    module,
+                    module_filename,
+                    template,
+                    template_filename,
+                    module_source,
+                    template_source):
+        self.module = module
+        self.module_filename = module_filename
+        self.template_filename = template_filename
+        self.module_source = module_source
+        self.template_source = template_source
+        self._modules[module.__name__] = template._mmarker = self
+        if module_filename:
+            self._modules[module_filename] = self
+
+    @property
+    def code(self):
+        if self.module_source is not None:
+            return self.module_source
+        else:
+            return util.read_file(self.module_filename)
+
+    @property
+    def source(self):
+        if self.template_source is not None:
+            if self.module._source_encoding and \
+                    not isinstance(self.template_source, str):
+                return self.template_source.decode(
+                                self.module._source_encoding)
+            else:
+                return self.template_source
+        else:
+            data = util.read_file(self.template_filename)
+            if self.module._source_encoding:
+                return data.decode(self.module._source_encoding)
+            else:
+                return data
+
+def _compile(template, text, filename, generate_magic_comment):
+    lexer = Lexer(text,
+                    filename,
+                    disable_unicode=template.disable_unicode,
+                    input_encoding=template.input_encoding,
+                    preprocessor=template.preprocessor)
+    node = lexer.parse()
+    source = codegen.compile(node,
+                            template.uri,
+                            filename,
+                            default_filters=template.default_filters,
+                            buffer_filters=template.buffer_filters,
+                            imports=template.imports,
+                            source_encoding=lexer.encoding,
+                            generate_magic_comment=generate_magic_comment,
+                            disable_unicode=template.disable_unicode,
+                            strict_undefined=template.strict_undefined,
+                            enable_loop=template.enable_loop,
+                            reserved_names=template.reserved_names)
+    return source, lexer
+
+def _compile_text(template, text, filename):
+    identifier = template.module_id
+    source, lexer = _compile(template, text, filename,
+                        generate_magic_comment=template.disable_unicode)
+
+    cid = identifier
+    if not util.py3k and isinstance(cid, str):
+        cid = cid.encode()
+    module = types.ModuleType(cid)
+    code = compile(source, cid, 'exec')
+    exec(code, module.__dict__, module.__dict__)
+    return (source, module)
+
+def _compile_module_file(template, text, filename, outputpath, module_writer):
+    identifier = template.module_id
+    source, lexer = _compile(template, text, filename,
+                        generate_magic_comment=True)
+
+    if isinstance(source, str):
+        source = source.encode(lexer.encoding or 'ascii')
+
+    if module_writer:
+        module_writer(source, outputpath)
+    else:
+        # make tempfiles in the same location as the ultimate
+        # location.   this ensures they're on the same filesystem,
+        # avoiding synchronization issues.
+        (dest, name) = tempfile.mkstemp(dir=os.path.dirname(outputpath))
+
+        os.write(dest, source)
+        os.close(dest)
+        shutil.move(name, outputpath)
+
+def _get_module_info_from_callable(callable_):
+    return _get_module_info(callable_.__globals__['__name__'])
+
+def _get_module_info(filename):
+    return ModuleInfo._modules[filename]
+
diff --git a/lib3/Mako-0.7.3/mako/util.py b/lib3/Mako-0.7.3/mako/util.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/mako/util.py
@@ -0,0 +1,437 @@
+# mako/util.py
+# Copyright (C) 2006-2012 the Mako authors and contributors <see AUTHORS file>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+import imp
+import sys
+
+
+py3k = getattr(sys, 'py3kwarning', False) or sys.version_info >= (3, 0)
+py26 = sys.version_info >= (2, 6)
+py25 = sys.version_info >= (2, 5)
+jython = sys.platform.startswith('java')
+win32 = sys.platform.startswith('win')
+pypy = hasattr(sys, 'pypy_version_info')
+
+if py3k:
+    from io import StringIO
+else:
+    try:
+        from io import StringIO
+    except:
+        from io import StringIO
+
+import codecs, re, weakref, os, time, operator
+import collections
+
+try:
+    import threading
+    import _thread
+except ImportError:
+    import dummy_threading as threading
+    import _dummy_thread as thread
+
+if win32 or jython:
+    time_func = time.clock
+else:
+    time_func = time.time
+
+def function_named(fn, name):
+    """Return a function with a given __name__.
+
+    Will assign to __name__ and return the original function if possible on
+    the Python implementation, otherwise a new function will be constructed.
+
+    """
+    fn.__name__ = name
+    return fn
+
+try:
+    from functools import partial
+except:
+    def partial(func, *args, **keywords):
+        def newfunc(*fargs, **fkeywords):
+            newkeywords = keywords.copy()
+            newkeywords.update(fkeywords)
+            return func(*(args + fargs), **newkeywords)
+        return newfunc
+
+if not py25:
+    def all(iterable):
+        for i in iterable:
+            if not i:
+                return False
+        return True
+
+    def exception_name(exc):
+        try:
+            return exc.__class__.__name__
+        except AttributeError:
+            return exc.__name__
+else:
+    all = all
+
+    def exception_name(exc):
+        return exc.__class__.__name__
+
+
+class PluginLoader(object):
+    def __init__(self, group):
+        self.group = group
+        self.impls = {}
+
+    def load(self, name):
+        if name in self.impls:
+            return self.impls[name]()
+        else:
+            import pkg_resources
+            for impl in pkg_resources.iter_entry_points(
+                                self.group,
+                                name):
+                self.impls[name] = impl.load
+                return impl.load()
+            else:
+                from mako import exceptions
+                raise exceptions.RuntimeException(
+                        "Can't load plugin %s %s" %
+                        (self.group, name))
+
+    def register(self, name, modulepath, objname):
+        def load():
+            mod = __import__(modulepath)
+            for token in modulepath.split(".")[1:]:
+                mod = getattr(mod, token)
+            return getattr(mod, objname)
+        self.impls[name] = load
+
+def verify_directory(dir):
+    """create and/or verify a filesystem directory."""
+
+    tries = 0
+
+    while not os.path.exists(dir):
+        try:
+            tries += 1
+            os.makedirs(dir, 0o775)
+        except:
+            if tries > 5:
+                raise
+
+def to_list(x, default=None):
+    if x is None:
+        return default
+    if not isinstance(x, (list, tuple)):
+        return [x]
+    else:
+        return x
+
+
+class memoized_property(object):
+    """A read-only @property that is only evaluated once."""
+    def __init__(self, fget, doc=None):
+        self.fget = fget
+        self.__doc__ = doc or fget.__doc__
+        self.__name__ = fget.__name__
+
+    def __get__(self, obj, cls):
+        if obj is None:
+            return self
+        obj.__dict__[self.__name__] = result = self.fget(obj)
+        return result
+
+class memoized_instancemethod(object):
+    """Decorate a method memoize its return value.
+
+    Best applied to no-arg methods: memoization is not sensitive to
+    argument values, and will always return the same value even when
+    called with different arguments.
+
+    """
+    def __init__(self, fget, doc=None):
+        self.fget = fget
+        self.__doc__ = doc or fget.__doc__
+        self.__name__ = fget.__name__
+
+    def __get__(self, obj, cls):
+        if obj is None:
+            return self
+        def oneshot(*args, **kw):
+            result = self.fget(obj, *args, **kw)
+            memo = lambda *a, **kw: result
+            memo.__name__ = self.__name__
+            memo.__doc__ = self.__doc__
+            obj.__dict__[self.__name__] = memo
+            return result
+        oneshot.__name__ = self.__name__
+        oneshot.__doc__ = self.__doc__
+        return oneshot
+
+class SetLikeDict(dict):
+    """a dictionary that has some setlike methods on it"""
+    def union(self, other):
+        """produce a 'union' of this dict and another (at the key level).
+
+        values in the second dict take precedence over that of the first"""
+        x = SetLikeDict(**self)
+        x.update(other)
+        return x
+
+class FastEncodingBuffer(object):
+    """a very rudimentary buffer that is faster than StringIO,
+    but doesn't crash on unicode data like cStringIO."""
+
+    def __init__(self, encoding=None, errors='strict', str=False):
+        self.data = collections.deque()
+        self.encoding = encoding
+        if str:
+            self.delim = ''
+        else:
+            self.delim = ''
+        self.str = str
+        self.errors = errors
+        self.write = self.data.append
+
+    def truncate(self):
+        self.data = collections.deque()
+        self.write = self.data.append
+
+    def getvalue(self):
+        if self.encoding:
+            return self.delim.join(self.data).encode(self.encoding,
+                                                     self.errors)
+        else:
+            return self.delim.join(self.data)
+
+class LRUCache(dict):
+    """A dictionary-like object that stores a limited number of items,
+    discarding lesser used items periodically.
+
+    this is a rewrite of LRUCache from Myghty to use a periodic timestamp-based
+    paradigm so that synchronization is not really needed.  the size management
+    is inexact.
+    """
+
+    class _Item(object):
+        def __init__(self, key, value):
+            self.key = key
+            self.value = value
+            self.timestamp = time_func()
+        def __repr__(self):
+            return repr(self.value)
+
+    def __init__(self, capacity, threshold=.5):
+        self.capacity = capacity
+        self.threshold = threshold
+
+    def __getitem__(self, key):
+        item = dict.__getitem__(self, key)
+        item.timestamp = time_func()
+        return item.value
+
+    def values(self):
+        return [i.value for i in dict.values(self)]
+
+    def setdefault(self, key, value):
+        if key in self:
+            return self[key]
+        else:
+            self[key] = value
+            return value
+
+    def __setitem__(self, key, value):
+        item = dict.get(self, key)
+        if item is None:
+            item = self._Item(key, value)
+            dict.__setitem__(self, key, item)
+        else:
+            item.value = value
+        self._manage_size()
+
+    def _manage_size(self):
+        while len(self) > self.capacity + self.capacity * self.threshold:
+            bytime = sorted(dict.values(self),
+                            key=operator.attrgetter('timestamp'), reverse=True)
+            for item in bytime[self.capacity:]:
+                try:
+                    del self[item.key]
+                except KeyError:
+                    # if we couldn't find a key, most likely some other thread
+                    # broke in on us. loop around and try again
+                    break
+
+# Regexp to match python magic encoding line
+_PYTHON_MAGIC_COMMENT_re = re.compile(
+    r'[ \t\f]* \# .* coding[=:][ \t]*([-\w.]+)',
+    re.VERBOSE)
+
+def parse_encoding(fp):
+    """Deduce the encoding of a Python source file (binary mode) from magic
+    comment.
+
+    It does this in the same way as the `Python interpreter`__
+
+    .. __: http://docs.python.org/ref/encodings.html
+
+    The ``fp`` argument should be a seekable file object in binary mode.
+    """
+    pos = fp.tell()
+    fp.seek(0)
+    try:
+        line1 = fp.readline()
+        has_bom = line1.startswith(codecs.BOM_UTF8)
+        if has_bom:
+            line1 = line1[len(codecs.BOM_UTF8):]
+
+        m = _PYTHON_MAGIC_COMMENT_re.match(line1.decode('ascii', 'ignore'))
+        if not m:
+            try:
+                import parser
+                parser.suite(line1.decode('ascii', 'ignore'))
+            except (ImportError, SyntaxError):
+                # Either it's a real syntax error, in which case the source
+                # is not valid python source, or line2 is a continuation of
+                # line1, in which case we don't want to scan line2 for a magic
+                # comment.
+                pass
+            else:
+                line2 = fp.readline()
+                m = _PYTHON_MAGIC_COMMENT_re.match(
+                                               line2.decode('ascii', 'ignore'))
+
+        if has_bom:
+            if m:
+                raise SyntaxError("python refuses to compile code with both a UTF8" \
+                      " byte-order-mark and a magic encoding comment")
+            return 'utf_8'
+        elif m:
+            return m.group(1)
+        else:
+            return None
+    finally:
+        fp.seek(pos)
+
+def sorted_dict_repr(d):
+    """repr() a dictionary with the keys in order.
+
+    Used by the lexer unit test to compare parse trees based on strings.
+
+    """
+    keys = list(d.keys())
+    keys.sort()
+    return "{" + ", ".join(["%r: %r" % (k, d[k]) for k in keys]) + "}"
+
+def restore__ast(_ast):
+    """Attempt to restore the required classes to the _ast module if it
+    appears to be missing them
+    """
+    if hasattr(_ast, 'AST'):
+        return
+    _ast.PyCF_ONLY_AST = 2 << 9
+    m = compile("""\
+def foo(): pass
+class Bar(object): pass
+if False: pass
+baz = 'mako'
+1 + 2 - 3 * 4 / 5
+6 // 7 % 8 << 9 >> 10
+11 & 12 ^ 13 | 14
+15 and 16 or 17
+-baz + (not +18) - ~17
+baz and 'foo' or 'bar'
+(mako is baz == baz) is not baz != mako
+mako > baz < mako >= baz <= mako
+mako in baz not in mako""", '<unknown>', 'exec', _ast.PyCF_ONLY_AST)
+    _ast.Module = type(m)
+
+    for cls in _ast.Module.__mro__:
+        if cls.__name__ == 'mod':
+            _ast.mod = cls
+        elif cls.__name__ == 'AST':
+            _ast.AST = cls
+
+    _ast.FunctionDef = type(m.body[0])
+    _ast.ClassDef = type(m.body[1])
+    _ast.If = type(m.body[2])
+
+    _ast.Name = type(m.body[3].targets[0])
+    _ast.Store = type(m.body[3].targets[0].ctx)
+    _ast.Str = type(m.body[3].value)
+
+    _ast.Sub = type(m.body[4].value.op)
+    _ast.Add = type(m.body[4].value.left.op)
+    _ast.Div = type(m.body[4].value.right.op)
+    _ast.Mult = type(m.body[4].value.right.left.op)
+
+    _ast.RShift = type(m.body[5].value.op)
+    _ast.LShift = type(m.body[5].value.left.op)
+    _ast.Mod = type(m.body[5].value.left.left.op)
+    _ast.FloorDiv = type(m.body[5].value.left.left.left.op)
+
+    _ast.BitOr = type(m.body[6].value.op)
+    _ast.BitXor = type(m.body[6].value.left.op)
+    _ast.BitAnd = type(m.body[6].value.left.left.op)
+
+    _ast.Or = type(m.body[7].value.op)
+    _ast.And = type(m.body[7].value.values[0].op)
+
+    _ast.Invert = type(m.body[8].value.right.op)
+    _ast.Not = type(m.body[8].value.left.right.op)
+    _ast.UAdd = type(m.body[8].value.left.right.operand.op)
+    _ast.USub = type(m.body[8].value.left.left.op)
+
+    _ast.Or = type(m.body[9].value.op)
+    _ast.And = type(m.body[9].value.values[0].op)
+
+    _ast.IsNot = type(m.body[10].value.ops[0])
+    _ast.NotEq = type(m.body[10].value.ops[1])
+    _ast.Is = type(m.body[10].value.left.ops[0])
+    _ast.Eq = type(m.body[10].value.left.ops[1])
+
+    _ast.Gt = type(m.body[11].value.ops[0])
+    _ast.Lt = type(m.body[11].value.ops[1])
+    _ast.GtE = type(m.body[11].value.ops[2])
+    _ast.LtE = type(m.body[11].value.ops[3])
+
+    _ast.In = type(m.body[12].value.ops[0])
+    _ast.NotIn = type(m.body[12].value.ops[1])
+
+
+try:
+    from inspect import CO_VARKEYWORDS, CO_VARARGS
+    def inspect_func_args(fn):
+        co = fn.__code__
+
+        nargs = co.co_argcount
+        names = co.co_varnames
+        args = list(names[:nargs])
+
+        varargs = None
+        if co.co_flags & CO_VARARGS:
+            varargs = co.co_varnames[nargs]
+            nargs = nargs + 1
+        varkw = None
+        if co.co_flags & CO_VARKEYWORDS:
+            varkw = co.co_varnames[nargs]
+
+        return args, varargs, varkw, fn.__defaults__
+except ImportError:
+    import inspect
+    def inspect_func_args(fn):
+        return inspect.getargspec(fn)
+
+def read_file(path, mode='rb'):
+    fp = open(path, mode)
+    try:
+        data = fp.read()
+        return data
+    finally:
+        fp.close()
+
+def load_module(module_id, path):
+    fp = open(path, 'rb')
+    try:
+        return imp.load_source(module_id, path, fp)
+    finally:
+        fp.close()
diff --git a/lib3/Mako-0.7.3/scripts/mako-render b/lib3/Mako-0.7.3/scripts/mako-render
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/scripts/mako-render
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+def render(data, kw):
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    lookup = TemplateLookup(["."])
+    return Template(data, lookup=lookup).render(**kw)
+
+def varsplit(var):
+    if "=" not in var:
+        return (var, "")
+    return var.split("=", 1)
+
+def main(argv=None):
+    from os.path import isfile
+    from sys import stdin
+
+    if argv is None:
+        import sys
+        argv = sys.argv
+
+    from optparse import OptionParser
+
+    parser = OptionParser("usage: %prog [FILENAME]")
+    parser.add_option("--var", default=[], action="append",
+                  help="variable (can be used multiple times, use name=value)")
+
+    opts, args = parser.parse_args(argv[1:])
+    if len(args) not in (0, 1):
+        parser.error("wrong number of arguments") # Will exit
+
+    if (len(args) == 0) or (args[0] == "-"):
+        fo = stdin
+    else:
+        filename = args[0]
+        if not isfile(filename):
+            raise SystemExit("error: can't find %s" % filename)
+        fo = open(filename)
+
+    kw = dict([varsplit(var) for var in opts.var])
+    data = fo.read()
+    print render(data, kw)
+
+if __name__ == "__main__":
+    main()
diff --git a/lib3/Mako-0.7.3/setup.cfg b/lib3/Mako-0.7.3/setup.cfg
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/setup.cfg
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/lib3/Mako-0.7.3/setup.py b/lib3/Mako-0.7.3/setup.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/setup.py
@@ -0,0 +1,62 @@
+from setuptools import setup, find_packages
+import os
+import re
+import sys
+
+extra = {}
+if sys.version_info >= (3, 0):
+    extra.update(
+        use_2to3=True,
+    )
+
+v = open(os.path.join(os.path.dirname(__file__), 'mako', '__init__.py'))
+VERSION = re.compile(r".*__version__ = '(.*?)'", re.S).match(v.read()).group(1)
+v.close()
+
+readme = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
+
+setup(name='Mako',
+      version=VERSION,
+      description="A super-fast templating language that borrows the \
+ best ideas from the existing templating languages.",
+      long_description=readme,
+      classifiers=[
+      'Development Status :: 5 - Production/Stable',
+      'Environment :: Web Environment',
+      'Intended Audience :: Developers',
+      'Programming Language :: Python',
+      'Programming Language :: Python :: 3',
+      "Programming Language :: Python :: Implementation :: CPython",
+      "Programming Language :: Python :: Implementation :: PyPy",
+      'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
+      ],
+      keywords='templates',
+      author='Mike Bayer',
+      author_email='mike at zzzcomputing.com',
+      url='http://www.makotemplates.org/',
+      license='MIT',
+      packages=find_packages('.', exclude=['examples*', 'test*']),
+      scripts=['scripts/mako-render'],
+      tests_require = ['nose >= 0.11'],
+      test_suite = "nose.collector",
+      zip_safe=False,
+      install_requires=[
+          'MarkupSafe>=0.9.2',
+      ],
+      extras_require = {'beaker':['Beaker>=1.1']},
+      entry_points="""
+      [python.templating.engines]
+      mako = mako.ext.turbogears:TGPlugin
+ 
+      [pygments.lexers]
+      mako = mako.ext.pygmentplugin:MakoLexer
+      html+mako = mako.ext.pygmentplugin:MakoHtmlLexer
+      xml+mako = mako.ext.pygmentplugin:MakoXmlLexer
+      js+mako = mako.ext.pygmentplugin:MakoJavascriptLexer
+      css+mako = mako.ext.pygmentplugin:MakoCssLexer
+
+      [babel.extractors]
+      mako = mako.ext.babelplugin:extract
+      """,
+      **extra
+)
diff --git a/lib3/Mako-0.7.3/test/__init__.py b/lib3/Mako-0.7.3/test/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/__init__.py
@@ -0,0 +1,145 @@
+from mako.template import Template
+import unittest, os
+from mako.util import py3k, py26, py25
+from mako.util import function_named
+import re
+from mako.cache import CacheImpl, register_plugin
+from nose import SkipTest
+
+
+template_base = os.path.join(os.path.dirname(__file__), 'templates')
+module_base = os.path.join(template_base, 'modules')
+
+class TemplateTest(unittest.TestCase):
+
+    def _file_template(self, filename, **kw):
+        filepath = self._file_path(filename)
+        return Template(uri=filename, filename=filepath,
+                            module_directory=module_base, **kw)
+
+    def _file_path(self, filename):
+        name, ext = os.path.splitext(filename)
+
+        if py3k:
+            py3k_path = os.path.join(template_base, name + "_py3k" + ext)
+            if os.path.exists(py3k_path):
+                return py3k_path
+
+        return os.path.join(template_base, filename)
+
+    def _do_file_test(self, filename, expected, filters=None,
+                        unicode_=True, template_args=None, **kw):
+        t1 = self._file_template(filename, **kw)
+        self._do_test(t1, expected, filters=filters,
+                        unicode_=unicode_, template_args=template_args)
+
+    def _do_memory_test(self, source, expected, filters=None,
+                        unicode_=True, template_args=None, **kw):
+        t1 = Template(text=source, **kw)
+        self._do_test(t1, expected, filters=filters,
+                        unicode_=unicode_, template_args=template_args)
+
+    def _do_test(self, template, expected, filters=None, template_args=None,
+                                unicode_=True):
+        if template_args is None:
+            template_args = {}
+        if unicode_:
+            output = template.render_unicode(**template_args)
+        else:
+            output = template.render(**template_args)
+
+        if filters:
+            output = filters(output)
+        eq_(output, expected)
+
+def eq_(a, b, msg=None):
+    """Assert a == b, with repr messaging on failure."""
+    assert a == b, msg or "%r != %r" % (a, b)
+
+def teardown():
+    import shutil
+    shutil.rmtree(module_base, True)
+
+def assert_raises(except_cls, callable_, *args, **kw):
+    try:
+        callable_(*args, **kw)
+        success = False
+    except except_cls as e:
+        success = True
+
+    # assert outside the block so it works for AssertionError too !
+    assert success, "Callable did not raise an exception"
+
+def assert_raises_message(except_cls, msg, callable_, *args, **kwargs):
+    try:
+        callable_(*args, **kwargs)
+        assert False, "Callable did not raise an exception"
+    except except_cls as e:
+        assert re.search(msg, str(e)), "%r !~ %s" % (msg, e)
+        print(str(e))
+
+def skip_if(predicate, reason=None):
+    """Skip a test if predicate is true."""
+    reason = reason or predicate.__name__
+
+    def decorate(fn):
+        fn_name = fn.__name__
+        def maybe(*args, **kw):
+            if predicate():
+                msg = "'%s' skipped: %s" % (
+                    fn_name, reason)
+                raise SkipTest(msg)
+            else:
+                return fn(*args, **kw)
+        return function_named(maybe, fn_name)
+    return decorate
+
+def requires_python_2(fn):
+    return skip_if(lambda: py3k, "Requires Python 2.xx")(fn)
+
+def requires_python_26_or_greater(fn):
+    return skip_if(lambda: not py26, "Requires Python 2.6 or greater")(fn)
+
+def requires_python_25_or_greater(fn):
+    return skip_if(lambda: not py25, "Requires Python 2.5 or greater")(fn)
+
+def requires_pygments_14(fn):
+    try:
+        import pygments
+        version = pygments.__version__
+    except:
+        version = "0"
+    return skip_if(lambda: version < "1.4")(fn)
+
+def requires_no_pygments(fn):
+    try:
+        import pygments
+    except:
+        pygments = None
+    return skip_if(lambda: pygments is not None)(fn)
+
+class PlainCacheImpl(CacheImpl):
+    """Simple memory cache impl so that tests which
+    use caching can run without beaker.  """
+
+    def __init__(self, cache):
+        self.cache = cache
+        self.data = {}
+
+    def get_or_create(self, key, creation_function, **kw):
+        if key in self.data:
+            return self.data[key]
+        else:
+            self.data[key] = data = creation_function(**kw)
+            return data
+
+    def put(self, key, value, **kw):
+        self.data[key] = value
+
+    def get(self, key, **kw):
+        return self.data[key]
+
+    def invalidate(self, key, **kw):
+        del self.data[key]
+
+register_plugin("plain", __name__, "PlainCacheImpl")
diff --git a/lib3/Mako-0.7.3/test/foo/__init__.py b/lib3/Mako-0.7.3/test/foo/__init__.py
new file mode 100644
diff --git a/lib3/Mako-0.7.3/test/foo/test_ns.py b/lib3/Mako-0.7.3/test/foo/test_ns.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/foo/test_ns.py
@@ -0,0 +1,7 @@
+def foo1(context):
+    context.write("this is foo1.")
+    return ''
+ 
+def foo2(context, x):
+    context.write("this is foo2, x is " + x)
+    return ''
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/sample_module_namespace.py b/lib3/Mako-0.7.3/test/sample_module_namespace.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/sample_module_namespace.py
@@ -0,0 +1,7 @@
+def foo1(context):
+    context.write("this is foo1.")
+    return ''
+ 
+def foo2(context, x):
+    context.write("this is foo2, x is " + x)
+    return ''
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/badbom.html b/lib3/Mako-0.7.3/test/templates/badbom.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/badbom.html
@@ -0,0 +1,2 @@
+## -*- coding: ascii -*-
+Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/bom.html b/lib3/Mako-0.7.3/test/templates/bom.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/bom.html
@@ -0,0 +1,1 @@
+Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/bommagic.html b/lib3/Mako-0.7.3/test/templates/bommagic.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/bommagic.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/chs_unicode.html b/lib3/Mako-0.7.3/test/templates/chs_unicode.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/chs_unicode.html
@@ -0,0 +1,11 @@
+## -*- encoding:utf8 -*-
+<%
+ msg = u'新中国的主席'
+%>
+
+<%def name="welcome(who, place=u'北京')">
+Welcome ${who} to ${place}.
+</%def>
+
+${name} 是 ${msg}<br/>
+${welcome(u'ä½ ')}
diff --git a/lib3/Mako-0.7.3/test/templates/chs_unicode_py3k.html b/lib3/Mako-0.7.3/test/templates/chs_unicode_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/chs_unicode_py3k.html
@@ -0,0 +1,11 @@
+## -*- encoding:utf8 -*-
+<%
+ msg = '新中国的主席'
+%>
+
+<%def name="welcome(who, place='北京')">
+Welcome ${who} to ${place}.
+</%def>
+
+${name} 是 ${msg}<br/>
+${welcome('ä½ ')}
diff --git a/lib3/Mako-0.7.3/test/templates/chs_utf8.html b/lib3/Mako-0.7.3/test/templates/chs_utf8.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/chs_utf8.html
@@ -0,0 +1,17 @@
+## -*- encoding:utf8 -*-
+<%
+ msg = '新中国的主席'
+%>
+
+<%def name="welcome(who, place='北京')">
+Welcome ${who} to ${place}.
+</%def>
+
+<%def name="welcome_buffered(who, place='北京')" buffered="True">
+Welcome ${who} to ${place}.
+</%def>
+
+${name} 是 ${msg}<br/>
+${welcome('ä½ ')}
+${welcome_buffered('ä½ ')}
+
diff --git a/lib3/Mako-0.7.3/test/templates/crlf.html b/lib3/Mako-0.7.3/test/templates/crlf.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/crlf.html
@@ -0,0 +1,19 @@
+<html>
+
+<%page args="a=['foo',
+                'bar']"/>
+
+like the name says.
+
+    % for x in [1,2,3]:
+        ${x}\
+    % endfor
+
+${trumpeter == 'Miles' and trumpeter or \
+      'Dizzy'}
+
+<%def name="hi()">
+    hi!
+</%def>
+
+</html>
diff --git a/lib3/Mako-0.7.3/test/templates/foo/modtest.html.py b/lib3/Mako-0.7.3/test/templates/foo/modtest.html.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/foo/modtest.html.py
@@ -0,0 +1,25 @@
+from mako import runtime, filters, cache
+UNDEFINED = runtime.UNDEFINED
+__M_dict_builtin = dict
+__M_locals_builtin = locals
+_magic_number = 5
+_modified_time = 1267565427.7968459
+_template_filename='/Users/classic/dev/mako/test/templates/modtest.html'
+_template_uri='/modtest.html'
+_template_cache=cache.Cache(__name__, _modified_time)
+_source_encoding=None
+_exports = []
+
+
+def render_body(context,**pageargs):
+    context.caller_stack._push_frame()
+    try:
+        __M_locals = __M_dict_builtin(pageargs=pageargs)
+        __M_writer = context.writer()
+        # SOURCE LINE 1
+        __M_writer('this is a test')
+        return ''
+    finally:
+        context.caller_stack._pop_frame()
+
+
diff --git a/lib3/Mako-0.7.3/test/templates/gettext.mako b/lib3/Mako-0.7.3/test/templates/gettext.mako
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/gettext.mako
@@ -0,0 +1,89 @@
+<%page args="x, y=_('Page arg 1'), z=_('Page arg 2')"/>
+<%!
+import random
+def gettext(message): return message
+_ = gettext
+def ungettext(s, p, c):
+    if c == 1:
+        return s
+    return p
+top = gettext('Begin')
+%>
+<%
+   # TRANSLATOR: Hi there!
+   hithere = _('Hi there!')
+
+   # TRANSLATOR: you should not be seeing this in the .po
+   rows = [[v for v in range(0,10)] for row in range(0,10)]
+
+   hello = _('Hello')
+%>
+<div id="header">
+  ${_('Welcome')}
+</div>
+<table>
+    % for row in (hithere, hello, _('Yo')):
+        ${makerow(row)}
+    % endfor
+    ${makerow(count=2)}
+</table>
+
+
+<div id="main">
+
+## TRANSLATOR: Ensure so and
+## so, thanks
+  ${_('The')} fuzzy ${ungettext('bunny', 'bunnies', random.randint(1, 2))}
+</div>
+
+<div id="footer">
+  ## TRANSLATOR: Good bye
+  ${_('Goodbye')}
+</div>
+ 
+<%def name="makerow(row=_('Babel'), count=1)">
+    <!-- ${ungettext('hella', 'hellas', count)} -->
+    % for i in range(count):
+      <tr>
+      % for name in row:
+          <td>${name}</td>\
+      % endfor
+      </tr>
+    % endfor
+</%def>
+
+<%def name="comment()">
+  <!-- ${caller.body()} -->
+</%def>
+
+<%block name="foo">
+    ## TRANSLATOR: Ensure so and
+    ## so, thanks
+      ${_('The')} fuzzy ${ungettext('bunny', 'bunnies', random.randint(1, 2))}
+</%block>
+
+<%call expr="comment">
+  P.S.
+  ## TRANSLATOR: HTML comment
+  ${_('Goodbye, really!')}
+</%call>
+
+<!-- ${_('P.S. byebye')} -->
+
+<div id="end">
+  <a href="#top">
+    ## TRANSLATOR: you won't see this either
+ 
+    ${_('Top')}
+  </a>
+</div>
+
+<%def name="panel()">
+
+${_(u'foo')} <%self:block_tpl title="123", name="_(u'baz')">
+
+${_(u'bar')}
+
+</%self:block_tpl>
+
+</%def>
diff --git a/lib3/Mako-0.7.3/test/templates/index.html b/lib3/Mako-0.7.3/test/templates/index.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/index.html
@@ -0,0 +1,1 @@
+this is index
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/internationalization.html b/lib3/Mako-0.7.3/test/templates/internationalization.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/internationalization.html
@@ -0,0 +1,920 @@
+<div class="rst-docs">
+ 
+  <h1 class="pudge-member-page-heading">Internationalization, Localization and Unicode</h1>
+ 
+  <table rules="none" frame="void" class="docinfo">
+<col class="docinfo-name"></col>
+<col class="docinfo-content"></col>
+<tbody valign="top">
+<tr><th class="docinfo-name">Author:</th>
+<td>James Gardner</td></tr>
+<tr class="field"><th class="docinfo-name">updated:</th><td class="field-body">2006-12-11</td>
+</tr>
+</tbody>
+</table>
+
+  <div class="note">
+<p class="first admonition-title">Note</p>
+<p>This is a work in progress. We hope the internationalization, localization
+and Unicode support in Pylons is now robust and flexible but we would
+appreciate hearing about any issues we have. Just drop a line to the
+pylons-discuss mailing list on Google Groups.</p>
+<p class="last">This is the first draft of the full document including Unicode. Expect
+some typos and spelling mistakes!</p>
+</div>
+<div class="contents topic">
+<p class="topic-title first"><a id="table-of-contents" name="table-of-contents">Table of Contents</a></p>
+<ul class="auto-toc simple">
+<li><a href="#understanding-unicode" id="id1" name="id1" class="reference">1   Understanding Unicode</a><ul class="auto-toc">
+<li><a href="#what-is-unicode" id="id2" name="id2" class="reference">1.1   What is Unicode?</a></li>
+<li><a href="#unicode-in-python" id="id3" name="id3" class="reference">1.2   Unicode in Python</a></li>
+<li><a href="#unicode-literals-in-python-source-code" id="id4" name="id4" class="reference">1.3   Unicode Literals in Python Source Code</a></li>
+<li><a href="#input-and-output" id="id5" name="id5" class="reference">1.4   Input and Output</a></li>
+<li><a href="#unicode-filenames" id="id6" name="id6" class="reference">1.5   Unicode Filenames</a></li>
+</ul>
+</li>
+<li><a href="#applying-this-to-web-programming" id="id7" name="id7" class="reference">2   Applying this to Web Programming</a><ul class="auto-toc">
+<li><a href="#request-parameters" id="id8" name="id8" class="reference">2.1   Request Parameters</a></li>
+<li><a href="#templating" id="id9" name="id9" class="reference">2.2   Templating</a></li>
+<li><a href="#output-encoding" id="id10" name="id10" class="reference">2.3   Output Encoding</a></li>
+<li><a href="#databases" id="id11" name="id11" class="reference">2.4   Databases</a></li>
+</ul>
+</li>
+<li><a href="#internationalization-and-localization" id="id12" name="id12" class="reference">3   Internationalization and Localization</a><ul class="auto-toc">
+<li><a href="#getting-started" id="id13" name="id13" class="reference">3.1   Getting Started</a></li>
+<li><a href="#testing-the-application" id="id14" name="id14" class="reference">3.2   Testing the Application</a></li>
+<li><a href="#missing-translations" id="id15" name="id15" class="reference">3.3   Missing Translations</a></li>
+<li><a href="#translations-within-templates" id="id16" name="id16" class="reference">3.4   Translations Within Templates</a></li>
+<li><a href="#producing-a-python-egg" id="id17" name="id17" class="reference">3.5   Producing a Python Egg</a></li>
+<li><a href="#plural-forms" id="id18" name="id18" class="reference">3.6   Plural Forms</a></li>
+</ul>
+</li>
+<li><a href="#summary" id="id19" name="id19" class="reference">4   Summary</a></li>
+<li><a href="#further-reading" id="id20" name="id20" class="reference">5   Further Reading</a></li>
+</ul>
+</div>
+<p>Internationalization and localization are means of adapting software for
+non-native environments, especially for other nations and cultures.</p>
+<p>Parts of an application which might need to be localized might include:</p>
+<blockquote>
+<ul class="simple">
+<li>Language</li>
+<li>Date/time format</li>
+<li>Formatting of numbers e.g. decimal points, positioning of separators,
+character used as separator</li>
+<li>Time zones (UTC in internationalized environments)</li>
+<li>Currency</li>
+<li>Weights and measures</li>
+</ul>
+</blockquote>
+<p>The distinction between internationalization and localization is subtle but
+important. Internationalization is the adaptation of products for potential use
+virtually everywhere, while localization is the addition of special features
+for use in a specific locale.</p>
+<p>For example, in terms of language used in software, internationalization is the
+process of marking up all strings that might need to be translated whilst
+localization is the process of producing translations for a particular locale.</p>
+<p>Pylons provides built-in support to enable you to internationalize language but
+leaves you to handle any other aspects of internationalization which might be
+appropriate to your application.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Internationalization is often abbreviated as I18N (or i18n or I18n) where the
+number 18 refers to the number of letters omitted.
+Localization is often abbreviated L10n or l10n in the same manner. These
+abbreviations also avoid picking one spelling (internationalisation vs.
+internationalization, etc.) over the other.</p>
+</div>
+<p>In order to represent characters from multiple languages, you will need to use
+Unicode so this documentation will start with a description of why Unicode is
+useful, its history and how to use Unicode in Python.</p>
+<div class="section">
+<h1><a href="#id1" id="understanding-unicode" name="understanding-unicode" class="toc-backref">1   Understanding Unicode</a></h1>
+<p>If you've ever come across text in a foreign language that contains lots of
+<tt class="docutils literal"><span class="pre">????</span></tt> characters or have written some Python code and received a message
+such as <tt class="docutils literal"><span class="pre">UnicodeDecodeError:</span> <span class="pre">'ascii'</span> <span class="pre">codec</span> <span class="pre">can't</span> <span class="pre">decode</span> <span class="pre">byte</span> <span class="pre">0xff</span> <span class="pre">in</span> <span class="pre">position</span>
+<span class="pre">6:</span> <span class="pre">ordinal</span> <span class="pre">not</span> <span class="pre">in</span> <span class="pre">range(128)</span></tt> then you have run into a problem with character
+sets, encodings, Unicode and the like.</p>
+<p>The truth is that many developers are put off by Unicode because most of the
+time it is possible to muddle through rather than take the time to learn the
+basics. To make the problem worse if you have a system that manages to fudge
+the issues and just about work and then start trying to do things properly with
+Unicode it often highlights problems in other parts of your code.</p>
+<p>The good news is that Python has great Unicode support, so the rest of
+this article will show you how to correctly use Unicode in Pylons to avoid
+unwanted <tt class="docutils literal"><span class="pre">?</span></tt> characters and <tt class="docutils literal"><span class="pre">UnicodeDecodeErrors</span></tt>.</p>
+<div class="section">
+<h2><a href="#id2" id="what-is-unicode" name="what-is-unicode" class="toc-backref">1.1   What is Unicode?</a></h2>
+<p>When computers were first being used the characters that were most important
+were unaccented English letters. Each of these letters could be represented by
+a number between 32 and 127 and thus was born ASCII, a character set where
+space was 32, the letter "A" was 65 and everything could be stored in 7 bits.</p>
+<p>Most computers in those days were using 8-bit bytes so people quickly realized
+that they could use the codes 128-255 for their own purposes. Different people
+used the codes 128-255 to represent different characters and before long these
+different sets of characters were also standardized into <em>code pages</em>. This
+meant that if you needed some non-ASCII characters in a document you could also
+specify a codepage which would define which extra characters were available.
+For example Israel DOS used a code page called 862, while Greek users used 737.
+This just about worked for Western languages provided you didn't want to write
+an Israeli document with Greek characters but it didn't work at all for Asian
+languages where there are many more characters than can be represented in 8
+bits.</p>
+<p>Unicode is a character set that solves these problems by uniquely defining
+<em>every</em> character that is used anywhere in the world. Rather than defining a
+character as a particular combination of bits in the way ASCII does, each
+character is assigned a <em>code point</em>. For example the word <tt class="docutils literal"><span class="pre">hello</span></tt> is made
+from code points <tt class="docutils literal"><span class="pre">U+0048</span> <span class="pre">U+0065</span> <span class="pre">U+006C</span> <span class="pre">U+006C</span> <span class="pre">U+006F</span></tt>. The full list of code
+points can be found at <a href="http://www.unicode.org/charts/" class="reference">http://www.unicode.org/charts/</a>.</p>
+<p>There are lots of different ways of encoding Unicode code points into bits but
+the most popular encoding is UTF-8. Using UTF-8, every code point from 0-127 is
+stored in a single byte. Only code points 128 and above are stored using 2, 3,
+in fact, up to 6 bytes. This has the useful side effect that English text looks
+exactly the same in UTF-8 as it did in ASCII, because for every
+ASCII character with hexadecimal value 0xXY, the corresponding Unicode
+code point is U+00XY. This backwards compatibility is why if you are developing
+an application that is only used by English speakers you can often get away
+without handling characters properly and still expect things to work most of
+the time. Of course, if you use a different encoding such as UTF-16 this
+doesn't apply since none of the code points are encoded to 8 bits.</p>
+<p>The important things to note from the discussion so far are that:</p>
+<ul>
+<li><p class="first">Unicode can represent pretty much any character in any writing system in
+widespread use today</p>
+</li>
+<li><p class="first">Unicode uses code points to represent characters and the way these map to bits
+in memory depends on the encoding</p>
+</li>
+<li><dl class="first docutils">
+<dt>The most popular encoding is UTF-8 which has  several convenient properties:</dt>
+<dd><ol class="first last arabic simple">
+<li>It can handle any Unicode code point</li>
+<li>A Unicode string is turned into a string of bytes containing no embedded
+zero bytes. This avoids byte-ordering issues, and means UTF-8 strings can be
+processed by C functions such as strcpy() and sent through protocols that can't
+handle zero bytes</li>
+<li>A string of ASCII text is also valid UTF-8 text</li>
+<li>UTF-8 is fairly compact; the majority of code points are turned into two
+bytes, and values less than 128 occupy only a single byte.</li>
+<li>If bytes are corrupted or lost, it's possible to determine the start of
+the next UTF-8-encoded code point and resynchronize.</li>
+</ol>
+</dd>
+</dl>
+</li>
+</ul>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Since Unicode 3.1, some extensions have even been defined so that the
+defined range is now U+000000 to U+10FFFF (21 bits), and formally, the
+character set is defined as 31-bits to allow for future expansion. It is a myth
+that there are 65,536 Unicode code points and that every Unicode letter can
+really be squeezed into two bytes. It is also incorrect to think that UTF-8 can
+represent less characters than UTF-16. UTF-8 simply uses a variable number of
+bytes for a character, sometimes just one byte (8 bits).</p>
+</div>
+</div>
+<div class="section">
+<h2><a href="#id3" id="unicode-in-python" name="unicode-in-python" class="toc-backref">1.2   Unicode in Python</a></h2>
+<p>In Python Unicode strings are expressed as instances of the built-in
+<tt class="docutils literal"><span class="pre">unicode</span></tt> type. Under the hood, Python represents Unicode strings as either
+16 or 32 bit integers, depending on how the Python interpreter was compiled.</p>
+<p>The <tt class="docutils literal"><span class="pre">unicode()</span></tt> constructor has the signature <tt class="docutils literal"><span class="pre">unicode(string[,</span> <span class="pre">encoding,</span>
+<span class="pre">errors])</span></tt>. All of its arguments should be 8-bit strings. The first argument is
+converted to Unicode using the specified encoding; if you leave off the
+encoding argument, the ASCII encoding is used for the conversion, so characters
+greater than 127 will be treated as errors:</p>
+<pre class="literal-block">
+>>> unicode('hello')
+u'hello'
+>>> s = unicode('hello')
+>>> type(s)
+<type 'unicode'>
+>>> unicode('hello' + chr(255))
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6:
+                    ordinal not in range(128)
+</pre>
+<p>The <tt class="docutils literal"><span class="pre">errors</span></tt> argument specifies what to do if the string can't be decoded to
+ascii. Legal values for this argument are <tt class="docutils literal"><span class="pre">'strict'</span></tt> (raise a
+<tt class="docutils literal"><span class="pre">UnicodeDecodeError</span></tt> exception), <tt class="docutils literal"><span class="pre">'replace'</span></tt> (replace the character that
+can't be decoded with another one), or <tt class="docutils literal"><span class="pre">'ignore'</span></tt> (just leave the character
+out of the Unicode result).</p>
+<blockquote>
+<pre class="doctest-block">
+>>> unicode('\x80abc', errors='strict')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0:
+                    ordinal not in range(128)
+>>> unicode('\x80abc', errors='replace')
+u'\ufffdabc'
+>>> unicode('\x80abc', errors='ignore')
+u'abc'
+</pre>
+</blockquote>
+<p>It is important to understand the difference between <em>encoding</em> and <em>decoding</em>.
+Unicode strings are considered to be the Unicode code points but any
+representation of the Unicode string has to be encoded to something else, for
+example UTF-8 or ASCII. So when you are converting an ASCII or UTF-8 string to
+Unicode you are <em>decoding</em> it and when you are converting from Unicode to UTF-8
+or ASCII you are <em>encoding</em> it. This is why the error in the example above says
+that the ASCII codec cannot decode the byte <tt class="docutils literal"><span class="pre">0x80</span></tt> from ASCII to Unicode
+because it is not in the range(128) or 0-127. In fact <tt class="docutils literal"><span class="pre">0x80</span></tt> is hex for 128
+which the first number outside the ASCII range. However if we tell Python that
+the character <tt class="docutils literal"><span class="pre">0x80</span></tt> is encoded with the <tt class="docutils literal"><span class="pre">'latin-1'</span></tt>, <tt class="docutils literal"><span class="pre">'iso_8859_1'</span></tt> or
+<tt class="docutils literal"><span class="pre">'8859'</span></tt> character sets (which incidentally are different names for the same
+thing) we get the result we expected:</p>
+<textarea name="code" class="python">
+>>> unicode('\x80', encoding='latin-1')
+u'\x80'
+</textarea><div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">The character encodings Python supports are listed at
+<a href="http://docs.python.org/lib/standard-encodings.html" class="reference">http://docs.python.org/lib/standard-encodings.html</a></p>
+</div>
+<p>Unicode objects in Python have most of the same methods that normal Python
+strings provide. Python will try to use the <tt class="docutils literal"><span class="pre">'ascii'</span></tt> codec to convert
+strings to Unicode if you do an operation on both types:</p>
+<textarea name="code" class="python">
+>>> a = 'hello'
+>>> b = unicode(' world!')
+>>> print a + b
+u'hello world!'
+</textarea><p>You can encode a Unicode string using a particular encoding like this:</p>
+<textarea name="code" class="python">
+>>> u'Hello World!'.encode('UTF-8')
+'Hello World!'
+</textarea></div>
+<div class="section">
+<h2><a href="#id4" id="unicode-literals-in-python-source-code" name="unicode-literals-in-python-source-code" class="toc-backref">1.3   Unicode Literals in Python Source Code</a></h2>
+<p>In Python source code, Unicode literals are written as strings prefixed with
+the 'u' or 'U' character:</p>
+<textarea name="code" class="python">
+>>> u'abcdefghijk'
+>>> U'lmnopqrstuv'
+</textarea><p>You can also use <tt class="docutils literal"><span class="pre">"</span></tt>, <tt class="docutils literal"><span class="pre">"""`</span></tt> or <tt class="docutils literal"><span class="pre">'''</span></tt> versions too. For example:</p>
+<textarea name="code" class="python">
+>>> u"""This
+... is a really long
+... Unicode string"""
+</textarea><p>Specific code points can be written using the <tt class="docutils literal"><span class="pre">\u</span></tt> escape sequence, which is
+followed by four hex digits giving the code point. If you use <tt class="docutils literal"><span class="pre">\U</span></tt> instead
+you specify 8 hex digits instead of 4. Unicode literals can also use the same
+escape sequences as 8-bit strings, including <tt class="docutils literal"><span class="pre">\x</span></tt>, but <tt class="docutils literal"><span class="pre">\x</span></tt> only takes two
+hex digits so it can't express all the available code points. You can add
+characters to Unicode strings using the <tt class="docutils literal"><span class="pre">unichr()</span></tt> built-in function and find
+out what the ordinal is with <tt class="docutils literal"><span class="pre">ord()</span></tt>.</p>
+<p>Here is an example demonstrating the different alternatives:</p>
+<textarea name="code" class="python">
+>>> s = u"\x66\u0072\u0061\U0000006e" + unichr(231) + u"ais"
+>>> #     ^^^^ two-digit hex escape
+>>> #         ^^^^^^ four-digit Unicode escape
+>>> #                     ^^^^^^^^^^ eight-digit Unicode escape
+>>> for c in s:  print ord(c),
+...
+97 102 114 97 110 231 97 105 115
+>>> print s
+franÁais
+</textarea><p>Using escape sequences for code points greater than 127 is fine in small doses
+but Python 2.4 and above support writing Unicode literals in any encoding as
+long as you declare the encoding being used by including a special comment as
+either the first or second line of the source file:</p>
+<textarea name="code" class="python">
+#!/usr/bin/env python
+# -*- coding: latin-1 -*-
+
+u = u'abcdÈ'
+print ord(u[-1])
+</textarea><p>If you don't include such a comment, the default encoding used will be ASCII.
+Versions of Python before 2.4 were Euro-centric and assumed Latin-1 as a
+default encoding for string literals; in Python 2.4, characters greater than
+127 still work but result in a warning. For example, the following program has
+no encoding declaration:</p>
+<textarea name="code" class="python">
+#!/usr/bin/env python
+u = u'abcdÈ'
+print ord(u[-1])
+</textarea><p>When you run it with Python 2.4, it will output the following warning:</p>
+<pre class="literal-block">
+sys:1: DeprecationWarning: Non-ASCII character '\xe9' in file testas.py on line
+2, but no encoding declared; see http://www.python.org/peps/pep-0263.html for de
+tails
+</pre>
+<p>and then the following output:</p>
+<pre class="literal-block">
+233
+</pre>
+<p>For real world use it is recommended that you use the UTF-8 encoding for your
+file but you must be sure that your text editor actually saves the file as
+UTF-8 otherwise the Python interpreter will try to parse UTF-8 characters but
+they will actually be stored as something else.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Windows users who use the <a href="http://www.scintilla.org/SciTE.html" class="reference">SciTE</a>
+editor can specify the encoding of their file from the menu using the
+<tt class="docutils literal"><span class="pre">File->Encoding</span></tt>.</p>
+</div>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">If you are working with Unicode in detail you might also be interested in
+the <tt class="docutils literal"><span class="pre">unicodedata</span></tt> module which can be used to find out Unicode properties
+such as a character's name, category, numeric value and the like.</p>
+</div>
+</div>
+<div class="section">
+<h2><a href="#id5" id="input-and-output" name="input-and-output" class="toc-backref">1.4   Input and Output</a></h2>
+<p>We now know how to use Unicode in Python source code but input and output can
+also be different using Unicode. Of course, some libraries natively support
+Unicode and if these libraries return Unicode objects you will not have to do
+anything special to support them. XML parsers and SQL databases frequently
+support Unicode for example.</p>
+<p>If you remember from the discussion earlier, Unicode data consists of code
+points. In order to send Unicode data via a socket or write it to a file you
+usually need to encode it to a series of bytes and then decode the data back to
+Unicode when reading it. You can of course perform the encoding manually
+reading a byte at the time but since encodings such as UTF-8 can have variable
+numbers of bytes per character it is usually much easier to use Python's
+built-in support in the form of the <tt class="docutils literal"><span class="pre">codecs</span></tt> module.</p>
+<p>The codecs module includes a version of the <tt class="docutils literal"><span class="pre">open()</span></tt> function that
+returns a file-like object that assumes the file's contents are in a specified
+encoding and accepts Unicode parameters for methods such as <tt class="docutils literal"><span class="pre">.read()</span></tt> and
+<tt class="docutils literal"><span class="pre">.write()</span></tt>.</p>
+<p>The function's parameters are open(filename, mode='rb', encoding=None,
+errors='strict', buffering=1). <tt class="docutils literal"><span class="pre">mode</span></tt> can be 'r', 'w', or 'a', just like the
+corresponding parameter to the regular built-in <tt class="docutils literal"><span class="pre">open()</span></tt> function. You can
+add a <tt class="docutils literal"><span class="pre">+</span></tt> character to update the file. <tt class="docutils literal"><span class="pre">buffering</span></tt> is similar to the
+standard function's parameter. <tt class="docutils literal"><span class="pre">encoding</span></tt> is a string giving the encoding to
+use, if not specified or specified as <tt class="docutils literal"><span class="pre">None</span></tt>, a regular Python file object
+that accepts 8-bit strings is returned.  Otherwise, a wrapper object is
+returned, and data written to or read from the wrapper object will be converted
+as needed. <tt class="docutils literal"><span class="pre">errors</span></tt> specifies the action for encoding errors and can be one
+of the usual values of <tt class="docutils literal"><span class="pre">'strict'</span></tt>, <tt class="docutils literal"><span class="pre">'ignore'</span></tt>, or <tt class="docutils literal"><span class="pre">'replace'</span></tt> which we
+saw right at the begining of this document when we were encoding strings in
+Python source files.</p>
+<p>Here is an example of how to read Unicode from a UTF-8 encoded file:</p>
+<textarea name="code" class="python">
+import codecs
+f = codecs.open('unicode.txt', encoding='utf-8')
+for line in f:
+    print repr(line)
+</textarea><p>It's also possible to open files in update mode, allowing both reading and writing:</p>
+<textarea name="code" class="python">
+f = codecs.open('unicode.txt', encoding='utf-8', mode='w+')
+f.write(u"\x66\u0072\u0061\U0000006e" + unichr(231) + u"ais")
+f.seek(0)
+print repr(f.readline()[:1])
+f.close()
+</textarea><p>Notice that we used the <tt class="docutils literal"><span class="pre">repr()</span></tt> function to display the Unicode data. This
+is very useful because if you tried to print the Unicode data directly, Python
+would need to encode it before it could be sent the console and depending on
+which characters were present and the character set used by the console, an
+error might be raised. This is avoided if you use <tt class="docutils literal"><span class="pre">repr()</span></tt>.</p>
+<p>The Unicode character <tt class="docutils literal"><span class="pre">U+FEFF</span></tt> is used as a byte-order mark or BOM, and is often
+written as the first character of a file in order to assist with auto-detection
+of the file's byte ordering. Some encodings, such as UTF-16, expect a BOM to be
+present at the start of a file, but with others such as UTF-8 it isn't necessary.</p>
+<p>When such an encoding is used, the BOM will be automatically written as the
+first character and will be silently dropped when the file is read. There are
+variants of these encodings, such as 'utf-16-le' and 'utf-16-be' for
+little-endian and big-endian encodings, that specify one particular byte
+ordering and don't skip the BOM.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Some editors including SciTE will put a byte order mark (BOM) in the text
+file when saved as UTF-8, which is strange because UTF-8 doesn't need BOMs.</p>
+</div>
+</div>
+<div class="section">
+<h2><a href="#id6" id="unicode-filenames" name="unicode-filenames" class="toc-backref">1.5   Unicode Filenames</a></h2>
+<p>Most modern operating systems support the use of Unicode filenames. The
+filenames are transparently converted to the underlying filesystem encoding.
+The type of encoding depends on the operating system.</p>
+<p>On Windows 9x, the encoding is <tt class="docutils literal"><span class="pre">mbcs</span></tt>.</p>
+<p>On Mac OS X, the encoding is <tt class="docutils literal"><span class="pre">utf-8</span></tt>.</p>
+<p>On Unix, the encoding is the user's preference according to the
+result of nl_langinfo(CODESET), or None if the nl_langinfo(CODESET) failed.</p>
+<p>On Windows NT+, file names are Unicode natively, so no conversion is performed.
+getfilesystemencoding still returns <tt class="docutils literal"><span class="pre">mbcs</span></tt>, as this is the encoding that
+applications should use when they explicitly want to convert Unicode strings to
+byte strings that are equivalent when used as file names.</p>
+<p><tt class="docutils literal"><span class="pre">mbcs</span></tt> is a special encoding for Windows that effectively means "use
+whichever encoding is appropriate". In Python 2.3 and above you can find out
+the system encoding with <tt class="docutils literal"><span class="pre">sys.getfilesystemencoding()</span></tt>.</p>
+<p>Most file and directory functions and methods support Unicode. For example:</p>
+<textarea name="code" class="python">
+filename = u"\x66\u0072\u0061\U0000006e" + unichr(231) + u"ais"
+f = open(filename, 'w')
+f.write('Some data\n')
+f.close()
+</textarea><p>Other functions such as <tt class="docutils literal"><span class="pre">os.listdir()</span></tt> will return Unicode if you pass a
+Unicode argument and will try to return strings if you pass an ordinary 8 bit
+string. For example running this example as <tt class="docutils literal"><span class="pre">test.py</span></tt>:</p>
+<textarea name="code" class="python">
+filename = u"Sample " + unichar(5000)
+f = open(filename, 'w')
+f.close()
+
+import os
+print os.listdir('.')
+print os.listdir(u'.')
+</textarea><p>will produce the following output:</p>
+<blockquote>
+['Sample?', 'test.py']
+[u'Sampleu1388', u'test.py']</blockquote>
+</div>
+</div>
+<div class="section">
+<h1><a href="#id7" id="applying-this-to-web-programming" name="applying-this-to-web-programming" class="toc-backref">2   Applying this to Web Programming</a></h1>
+<p>So far we've seen how to use encoding in source files and seen how to decode
+text to Unicode and encode it back to text. We've also seen that Unicode
+objects can be manipulated in similar ways to strings and we've seen how to
+perform input and output operations on files. Next we are going to look at how
+best to use Unicode in a web app.</p>
+<p>The main rule is this:</p>
+<pre class="literal-block">
+Your application should use Unicode for all strings internally, decoding
+any input to Unicode as soon as it enters the application and encoding the
+Unicode to UTF-8 or another encoding only on output.
+</pre>
+<p>If you fail to do this you will find that <tt class="docutils literal"><span class="pre">UnicodeDecodeError</span></tt> s will start
+popping up in unexpected places when Unicode strings are used with normal 8-bit
+strings because Python's default encoding is ASCII and it will try to decode
+the text to ASCII and fail. It is always better to do any encoding or decoding
+at the edges of your application otherwise you will end up patching lots of
+different parts of your application unnecessarily as and when errors pop up.</p>
+<p>Unless you have a very good reason not to it is wise to use UTF-8 as the
+default encoding since it is so widely supported.</p>
+<p>The second rule is:</p>
+<pre class="literal-block">
+Always test your application with characters above 127 and above 255
+wherever possible.
+</pre>
+<p>If you fail to do this you might think your application is working fine, but as
+soon as your users do put in non-ASCII characters you will have problems.
+Using arabic is always a good test and www.google.ae is a good source of sample
+text.</p>
+<p>The third rule is:</p>
+<pre class="literal-block">
+Always do any checking of a string for illegal characters once it's in the
+form that will be used or stored, otherwise the illegal characters might be
+disguised.
+</pre>
+<p>For example, let's say you have a content management system that takes a
+Unicode filename, and you want to disallow paths with a '/' character. You
+might write this code:</p>
+<textarea name="code" class="python">
+def read_file(filename, encoding):
+    if '/' in filename:
+        raise ValueError("'/' not allowed in filenames")
+    unicode_name = filename.decode(encoding)
+    f = open(unicode_name, 'r')
+    # ... return contents of file ...
+</textarea><p>This is INCORRECT. If an attacker could specify the 'base64' encoding, they
+could pass <tt class="docutils literal"><span class="pre">L2V0Yy9wYXNzd2Q=</span></tt> which is the base-64 encoded form of the string
+<tt class="docutils literal"><span class="pre">'/etc/passwd'</span></tt> which is a file you clearly don't want an attacker to get
+hold of.  The above code looks for <tt class="docutils literal"><span class="pre">/</span></tt> characters in the encoded form and
+misses the dangerous character in the resulting decoded form.</p>
+<p>Those are the three basic rules so now we will look at some of the places you
+might want to perform Unicode decoding in a Pylons application.</p>
+<div class="section">
+<h2><a href="#id8" id="request-parameters" name="request-parameters" class="toc-backref">2.1   Request Parameters</a></h2>
+<p>Currently the Pylons input values come from <tt class="docutils literal"><span class="pre">request.params</span></tt> but these are
+not decoded to Unicode by default because not all input should be assumed to be
+Unicode data.</p>
+<p>If you would like However you can use the two functions below:</p>
+<textarea name="code" class="python">
+def decode_multi_dict(md, encoding="UTF-8", errors="strict"):
+    """Given a MultiDict, decode all its parts from the given encoding.
+
+    This modifies the MultiDict in place.
+
+    encoding, strict
+      These are passed to the decode function.
+
+    """
+    items = md.items()
+    md.clear()
+    for (k, v) in items:
+        md.add(k.decode(encoding, errors),
+               v.decode(encoding, errors))
+
+
+def decode_request(request, encoding="UTF-8", errors="strict"):
+    """Given a request object, decode GET and POST in place.
+
+    This implicitly takes care of params as well.
+
+    """
+    decode_multi_dict(request.GET, encoding, errors)
+    decode_multi_dict(request.POST, encoding, errors)
+</textarea><p>These can then be used as follows:</p>
+<textarea name="code" class="python">
+unicode_params = decode_request(request.params)
+</textarea><p>This code is discussed in <a href="http://pylonshq.com/project/pylonshq/ticket/135" class="reference">ticket 135</a> but shouldn't be used with
+file uploads since these shouldn't ordinarily be decoded to Unicode.</p>
+</div>
+<div class="section">
+<h2><a href="#id9" id="templating" name="templating" class="toc-backref">2.2   Templating</a></h2>
+<p>Pylons uses Myghty as its default templating language and Myghty 1.1 and above
+fully support Unicode. The Myghty documentation explains how to use Unicode and
+you at <a href="http://www.myghty.org/docs/unicode.myt" class="reference">http://www.myghty.org/docs/unicode.myt</a> but the important idea is that
+you can Unicode literals pretty much anywhere you can use normal 8-bit strings
+including in <tt class="docutils literal"><span class="pre">m.write()</span></tt> and <tt class="docutils literal"><span class="pre">m.comp()</span></tt>. You can also pass Unicode data to
+Pylons' <tt class="docutils literal"><span class="pre">render_response()</span></tt> and <tt class="docutils literal"><span class="pre">Response()</span></tt> callables.</p>
+<p>Any Unicode data output by Myghty is automatically decoded to whichever
+encoding you have chosen. The default is UTF-8 but you can choose which
+encoding to use by editing your project's <tt class="docutils literal"><span class="pre">config/environment.py</span></tt> file and
+adding an option like this:</p>
+<textarea name="code" class="python">
+# Add your own Myghty config options here, note that all config options will override
+# any Pylons config options
+
+myghty['output_encoding'] = 'UTF-8'
+</textarea><p>replacing <tt class="docutils literal"><span class="pre">UTF-8</span></tt> with the encoding you wish to use.</p>
+<p>If you need to disable Unicode support altogether you can set this:</p>
+<textarea name="code" class="python">
+myghty['disable_unicode'] = True
+</textarea><p>but again, you would have to have a good reason to want to do this.</p>
+</div>
+<div class="section">
+<h2><a href="#id10" id="output-encoding" name="output-encoding" class="toc-backref">2.3   Output Encoding</a></h2>
+<p>Web pages should be generated with a specific encoding, most likely UTF-8. At
+the very least, that means you should specify the following in the <tt class="docutils literal"><span class="pre"><head></span></tt>
+section:</p>
+<pre class="literal-block">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</pre>
+<p>You should also set the charset in the <tt class="docutils literal"><span class="pre">Content-Type</span></tt> header:</p>
+<textarea name="code" class="python">
+respones = Response(...)
+response.headers['Content-type'] = 'text/html; charset=utf-8'
+</textarea><p>If you specify that your output is UTF-8, generally the web browser will
+give you UTF-8. If you want the browser to submit data using a different
+character set, you can set the encoding by adding the <tt class="docutils literal"><span class="pre">accept-encoding</span></tt>
+tag to your form. Here is an example:</p>
+<pre class="literal-block">
+<form accept-encoding="US-ASCII" ...>
+</pre>
+<p>However, be forewarned that if the user tries to give you non-ASCII
+text, then:</p>
+<blockquote>
+<ul class="simple">
+<li>Firefox will translate the non-ASCII text into HTML entities.</li>
+<li>IE will ignore your suggested encoding and give you UTF-8 anyway.</li>
+</ul>
+</blockquote>
+<p>The lesson to be learned is that if you output UTF-8, you had better be
+prepared to accept UTF-8 by decoding the data in <tt class="docutils literal"><span class="pre">request.params</span></tt> as
+described in the section above entitled "Request Parameters".</p>
+<p>Another technique which is sometimes used to determine the character set is to
+use an algorithm to analyse the input and guess the encoding based on
+probabilities.</p>
+<p>For instance, if you get a file, and you don't know what encoding it is encoded
+in, you can often rename the file with a .txt extension and then try to open it
+in Firefox.  Then you can use the "View->Character Encoding" menu to try to
+auto-detect the encoding.</p>
+</div>
+<div class="section">
+<h2><a href="#id11" id="databases" name="databases" class="toc-backref">2.4   Databases</a></h2>
+<p>Your database driver should automatically convert from Unicode objects to a
+particular charset when writing and back again when reading. Again it is normal
+to use UTF-8 which is well supported.</p>
+<p>You should check your database's documentation for information on how it handles
+Unicode.</p>
+<p>For example MySQL's Unicode documentation is here
+<a href="http://dev.mysql.com/doc/refman/5.0/en/charset-unicode.html" class="reference">http://dev.mysql.com/doc/refman/5.0/en/charset-unicode.html</a></p>
+<p>Also note that you need to consider both the encoding of the database
+and the encoding used by the database driver.</p>
+<p>If you're using MySQL together with SQLAlchemy, see the following, as
+there are some bugs in MySQLdb that you'll need to work around:</p>
+<p><a href="http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg00366.html" class="reference">http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg00366.html</a></p>
+</div>
+</div>
+<div class="section">
+<h1><a href="#id12" id="internationalization-and-localization" name="internationalization-and-localization" class="toc-backref">3   Internationalization and Localization</a></h1>
+<p>By now you should have a good idea of what Unicode is, how to use it in Python
+and which areas of you application need to pay specific attention to decoding and
+encoding Unicode data.</p>
+<p>This final section will look at the issue of making your application work with
+multiple languages.</p>
+<div class="section">
+<h2><a href="#id13" id="getting-started" name="getting-started" class="toc-backref">3.1   Getting Started</a></h2>
+<p>Everywhere in your code where you want strings to be available in different
+languages you wrap them in the <tt class="docutils literal"><span class="pre">_()</span></tt> function. There
+are also a number of other translation functions which are documented in the API reference at
+<a href="http://pylonshq.com/docs/module-pylons.i18n.translation.html" class="reference">http://pylonshq.com/docs/module-pylons.i18n.translation.html</a></p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">The <tt class="docutils literal"><span class="pre">_()</span></tt> function is a reference to the <tt class="docutils literal"><span class="pre">ugettext()</span></tt> function.
+<tt class="docutils literal"><span class="pre">_()</span></tt> is a convention for marking text to be translated and saves on keystrokes.
+<tt class="docutils literal"><span class="pre">ugettext()</span></tt> is the Unicode version of <tt class="docutils literal"><span class="pre">gettext()</span></tt>.</p>
+</div>
+<p>In our example we want the string <tt class="docutils literal"><span class="pre">'Hello'</span></tt> to appear in three different
+languages: English, French and Spanish. We also want to display the word
+<tt class="docutils literal"><span class="pre">'Hello'</span></tt> in the default language. We'll then go on to use some pural words
+too.</p>
+<p>Lets call our project <tt class="docutils literal"><span class="pre">translate_demo</span></tt>:</p>
+<pre class="literal-block">
+paster create --template=pylons translate_demo
+</pre>
+<p>Now lets add a friendly controller that says hello:</p>
+<pre class="literal-block">
+cd translate_demo
+paster controller hello
+</pre>
+<p>Edit <tt class="docutils literal"><span class="pre">controllers/hello.py</span></tt> controller to look like this making use of the
+<tt class="docutils literal"><span class="pre">_()</span></tt> function everywhere where the string <tt class="docutils literal"><span class="pre">Hello</span></tt> appears:</p>
+<textarea name="code" class="python">
+from translate_demo.lib.base import *
+
+class HelloController(BaseController):
+
+    def index(self):
+        resp = Response()
+        resp.write('Default: %s<br />' % _('Hello'))
+        for lang in ['fr','en','es']:
+            h.set_lang(lang)
+            resp.write("%s: %s<br />" % (h.get_lang(), _('Hello')))
+        return resp
+</textarea><p>When writing your controllers it is important not to piece sentences together manually because
+certain languages might need to invert the grammars. As an example this is bad:</p>
+<textarea name="code" class="python">
+# BAD!
+msg = _("He told her ")
+msg += _("not to go outside.")
+</textarea><p>but this is perfectly acceptable:</p>
+<textarea name="code" class="python">
+# GOOD
+msg = _("He told her not to go outside")
+</textarea><p>The controller has now been internationalized but it will raise a <tt class="docutils literal"><span class="pre">LanguageError</span></tt>
+until we have specified the alternative languages.</p>
+<p>Pylons uses <a href="http://www.gnu.org/software/gettext/" class="reference">GNU gettext</a> to handle
+internationalization. GNU gettext use three types of files in the
+translation framework.</p>
+<p>POT (Portable Object Template) files</p>
+<blockquote>
+The first step in the localization process. A program is used to search through
+your project's source code and pick out every string passed to one of the
+translation functions, such as <tt class="docutils literal"><span class="pre">_()</span></tt>. This list is put together in a
+specially-formatted template file that will form the basis of all
+translations. This is the <tt class="docutils literal"><span class="pre">.pot</span></tt> file.</blockquote>
+<p>PO (Portable Object) files</p>
+<blockquote>
+The second step in the localization process. Using the POT file as a template,
+the list of messages are translated and saved as a <tt class="docutils literal"><span class="pre">.po</span></tt> file.</blockquote>
+<p>MO (Machine Object) files</p>
+<blockquote>
+The final step in the localization process. The PO file is run through a
+program that turns it into an optimized machine-readable binary file, which is
+the <tt class="docutils literal"><span class="pre">.mo</span></tt> file. Compiling the translations to machine code makes the
+localized program much faster in retrieving the translations while it is
+running.</blockquote>
+<p>Versions of Pylons prior to 0.9.4 came with a setuptools extension to help with
+the extraction of strings and production of a <tt class="docutils literal"><span class="pre">.mo</span></tt> file. The implementation
+did not support Unicode nor the ungettext function and was therfore dropped in
+Python 0.9.4.</p>
+<p>You will therefore need to use an external program to perform these tasks.  You
+may use whichever you prefer but <tt class="docutils literal"><span class="pre">xgettext</span></tt> is highly recommended. Python's
+gettext utility has some bugs, especially regarding plurals.</p>
+<p>Here are some compatible tools and projects:</p>
+<p>The Rosetta Project (<a href="https://launchpad.ubuntu.com/rosetta/" class="reference">https://launchpad.ubuntu.com/rosetta/</a>)</p>
+<blockquote>
+The Ubuntu Linux project has a web site that allows you to translate
+messages without even looking at a PO or POT file, and export directly to a MO.</blockquote>
+<p>poEdit (<a href="http://www.poedit.org/" class="reference">http://www.poedit.org/</a>)</p>
+<blockquote>
+An open source program for Windows and UNIX/Linux which provides an easy-to-use
+GUI for editing PO files and generating MO files.</blockquote>
+<p>KBabel (<a href="http://i18n.kde.org/tools/kbabel/" class="reference">http://i18n.kde.org/tools/kbabel/</a>)</p>
+<blockquote>
+Another open source PO editing program for KDE.</blockquote>
+<p>GNU Gettext (<a href="http://www.gnu.org/software/gettext/" class="reference">http://www.gnu.org/software/gettext/</a>)</p>
+<blockquote>
+The official Gettext tools package contains command-line tools for creating
+POTs, manipulating POs, and generating MOs. For those comfortable with a
+command shell.</blockquote>
+<p>As an example we will quickly discuss the use of poEdit which is cross platform
+and has a GUI which makes it easier to get started with.</p>
+<p>To use poEdit with the <tt class="docutils literal"><span class="pre">translate_demo</span></tt> you would do the following:</p>
+<ol class="arabic simple">
+<li>Download and install poEdit.</li>
+<li>A dialog pops up. Fill in <em>all</em> the fields you can on the <tt class="docutils literal"><span class="pre">Project</span> <span class="pre">Info</span></tt> tab, enter the path to your project on the <tt class="docutils literal"><span class="pre">Paths</span></tt> tab (ie <tt class="docutils literal"><span class="pre">/path/to/translate_demo</span></tt>) and enter the following keywords on separate lines on the <tt class="docutils literal"><span class="pre">keywords</span></tt> tab: <tt class="docutils literal"><span class="pre">_</span></tt>, <tt class="docutils literal"><span class="pre">N_</span></tt>, <tt class="docutils literal"><span class="pre">ugettext</span></tt>, <tt class="docutils literal"><span class="pre">gettext</span></tt>, <tt class="docutils literal"><span class="pre">ngettext</span></tt>, <tt class="docutils literal"><span class="pre">ungettext</span></tt>.</li>
+<li>Click OK</li>
+</ol>
+<p>poEdit will search your source tree and find all the strings you have marked
+up. You can then enter your translations in whatever charset you chose in
+the project info tab. UTF-8 is a good choice.</p>
+<p>Finally, after entering your translations you then save the catalog and rename
+the <tt class="docutils literal"><span class="pre">.mo</span></tt> file produced to <tt class="docutils literal"><span class="pre">translate_demo.mo</span></tt> and put it in the
+<tt class="docutils literal"><span class="pre">translate_demo/i18n/es/LC_MESSAGES</span></tt> directory or whatever is appropriate for
+your translation.</p>
+<p>You will need to repeat the process of creating a <tt class="docutils literal"><span class="pre">.mo</span></tt> file for the <tt class="docutils literal"><span class="pre">fr</span></tt>,
+<tt class="docutils literal"><span class="pre">es</span></tt> and <tt class="docutils literal"><span class="pre">en</span></tt> translations.</p>
+<p>The relevant lines from <tt class="docutils literal"><span class="pre">i18n/en/LC_MESSAGES/translate_demo.po</span></tt> look like this:</p>
+<pre class="literal-block">
+#: translate_demo\controllers\hello.py:6 translate_demo\controllers\hello.py:9
+msgid "Hello"
+msgstr "Hello"
+</pre>
+<p>The relevant lines from <tt class="docutils literal"><span class="pre">i18n/es/LC_MESSAGES/translate_demo.po</span></tt> look like this:</p>
+<pre class="literal-block">
+#: translate_demo\controllers\hello.py:6 translate_demo\controllers\hello.py:9
+msgid "Hello"
+msgstr "°Hola!"
+</pre>
+<p>The relevant lines from <tt class="docutils literal"><span class="pre">i18n/fr/LC_MESSAGES/translate_demo.po</span></tt> look like this:</p>
+<pre class="literal-block">
+#: translate_demo\controllers\hello.py:6 translate_demo\controllers\hello.py:9
+msgid "Hello"
+msgstr "Bonjour"
+</pre>
+<p>Whichever tools you use you should end up with an <tt class="docutils literal"><span class="pre">i18n</span></tt> directory that looks
+like this when you have finished:</p>
+<pre class="literal-block">
+i18n/en/LC_MESSAGES/translate_demo.po
+i18n/en/LC_MESSAGES/translate_demo.mo
+i18n/es/LC_MESSAGES/translate_demo.po
+i18n/es/LC_MESSAGES/translate_demo.mo
+i18n/fr/LC_MESSAGES/translate_demo.po
+i18n/fr/LC_MESSAGES/translate_demo.mo
+</pre>
+</div>
+<div class="section">
+<h2><a href="#id14" id="testing-the-application" name="testing-the-application" class="toc-backref">3.2   Testing the Application</a></h2>
+<p>Start the server with the following command:</p>
+<pre class="literal-block">
+paster serve --reload development.ini
+</pre>
+<p>Test your controller by visiting <a href="http://localhost:5000/hello" class="reference">http://localhost:5000/hello</a>. You should see
+the following output:</p>
+<pre class="literal-block">
+Default: Hello
+fr: Bonjour
+en: Hello
+es: °Hola!
+</pre>
+<p>You can now set the language used in a controller on the fly.</p>
+<p>For example this could be used to allow a user to set which language they
+wanted your application to work in. You could save the value to the session
+object:</p>
+<textarea name="code" class="python">
+session['lang'] = 'en'
+</textarea><p>then on each controller call the language to be used could be read from the
+session and set in your controller's <tt class="docutils literal"><span class="pre">__before__()</span></tt> method so that the pages
+remained in the same language that was previously set:</p>
+<textarea name="code" class="python">
+def __before__(self, action):
+    if session.has_key('lang'):
+        h.set_lang(session['lang'])
+</textarea><p>One more useful thing to be able to do is to set the default language to be
+used in the configuration file. Just add a <tt class="docutils literal"><span class="pre">lang</span></tt> variable together with the
+code of the language you wanted to use in your <tt class="docutils literal"><span class="pre">development.ini</span></tt> file. For
+example to set the default language to Spanish you would add <tt class="docutils literal"><span class="pre">lang</span> <span class="pre">=</span> <span class="pre">es</span></tt> to
+your <tt class="docutils literal"><span class="pre">development.ini</span></tt>. The relevant part from the file might look something
+like this:</p>
+<textarea name="code" class="pasteini">
+[app:main]
+use = egg:translate_demo
+lang = es
+</textarea><p>If you are running the server with the <tt class="docutils literal"><span class="pre">--reload</span></tt> option the server will
+automatically restart if you change the <tt class="docutils literal"><span class="pre">development.ini</span></tt> file. Otherwise
+restart the server manually and the output would this time be as follows:</p>
+<pre class="literal-block">
+Default: °Hola!
+fr: Bonjour
+en: Hello
+es: °Hola!
+</pre>
+</div>
+<div class="section">
+<h2><a href="#id15" id="missing-translations" name="missing-translations" class="toc-backref">3.3   Missing Translations</a></h2>
+<p>If your code calls <tt class="docutils literal"><span class="pre">_()</span></tt> with a string that doesn't exist in your language
+catalogue, the string passed to <tt class="docutils literal"><span class="pre">_()</span></tt> is returned instead.</p>
+<p>Modify the last line of the hello controller to look like this:</p>
+<textarea name="code" class="python">
+resp.write("%s: %s %s<br />" % (h.get_lang(), _('Hello'), _('World!')))
+</textarea><div class="warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">Of course, in real life breaking up sentences in this way is very dangerous because some
+grammars might require the order of the words to be different.</p>
+</div>
+<p>If you run the example again the output will be:</p>
+<pre class="literal-block">
+Default: °Hola!
+fr: Bonjour World!
+en: Hello World!
+es: °Hola! World!
+</pre>
+<p>This is because we never provided a translation for the string <tt class="docutils literal"><span class="pre">'World!'</span></tt> so
+the string itself is used.</p>
+</div>
+<div class="section">
+<h2><a href="#id16" id="translations-within-templates" name="translations-within-templates" class="toc-backref">3.4   Translations Within Templates</a></h2>
+<p>You can also use the <tt class="docutils literal"><span class="pre">_()</span></tt> function within templates in exactly the same way
+you do in code. For example:</p>
+<textarea name="code" class="html">
+<% _('Hello') %>
+</textarea><p>would produce the string <tt class="docutils literal"><span class="pre">'Hello'</span></tt> in the language you had set.</p>
+<p>There is one complication though. gettext's <tt class="docutils literal"><span class="pre">xgettext</span></tt> command can only extract
+strings that need translating from Python code in <tt class="docutils literal"><span class="pre">.py</span></tt> files. This means
+that if you write <tt class="docutils literal"><span class="pre">_('Hello')</span></tt> in a template such as a Myghty template,
+<tt class="docutils literal"><span class="pre">xgettext</span></tt> will not find the string <tt class="docutils literal"><span class="pre">'Hello'</span></tt> as one which needs
+translating.</p>
+<p>As long as <tt class="docutils literal"><span class="pre">xgettext</span></tt> can find a string marked for translation with one
+of the translation functions and defined in Python code in your project
+filesystem it will manage the translation when the same string is defined in a
+Myghty template and marked for translation.</p>
+<p>One solution to ensure all strings are picked up for translation is to create a
+file in <tt class="docutils literal"><span class="pre">lib</span></tt> with an appropriate filename, <tt class="docutils literal"><span class="pre">i18n.py</span></tt> for example, and then
+add a list of all the strings which appear in your templates so that your
+translation tool can then extract the strings in <tt class="docutils literal"><span class="pre">lib/i18n.py</span></tt> for
+translation and use the translated versions in your templates as well.</p>
+<p>For example if you wanted to ensure the translated string <tt class="docutils literal"><span class="pre">'Good</span> <span class="pre">Morning'</span></tt>
+was available in all templates you could create a <tt class="docutils literal"><span class="pre">lib/i18n.py</span></tt> file that
+looked something like this:</p>
+<textarea name="code" class="python">
+from base import _
+_('Good Morning')
+</textarea><p>This approach requires quite a lot of work and is rather fragile. The best
+solution if you are using a templating system such as Myghty or Cheetah which
+uses compiled Python files is to use a Makefile to ensure that every template
+is compiled to Python before running the extraction tool to make sure that
+every template is scanned.</p>
+<p>Of course, if your cache directory is in the default location or elsewhere
+within your project's filesystem, you will probably find that all templates
+have been compiled as Python files during the course of the development process.
+This means that your tool's extraction command will successfully pick up
+strings to translate from the cached files anyway.</p>
+<p>You may also find that your extraction tool is capable of extracting the
+strings correctly from the template anyway, particularly if the templating
+langauge is quite similar to Python. It is best not to rely on this though.</p>
+</div>
+<div class="section">
+<h2><a href="#id17" id="producing-a-python-egg" name="producing-a-python-egg" class="toc-backref">3.5   Producing a Python Egg</a></h2>
+<p>Finally you can produce an egg of your project which includes the translation
+files like this:</p>
+<pre class="literal-block">
+python setup.py bdist_egg
+</pre>
+<p>The <tt class="docutils literal"><span class="pre">setup.py</span></tt> automatically includes the <tt class="docutils literal"><span class="pre">.mo</span></tt> language catalogs your
+application needs so that your application can be distributed as an egg. This
+is done with the following line in your <tt class="docutils literal"><span class="pre">setup.py</span></tt> file:</p>
+<pre class="literal-block">
+package_data={'translate_demo': ['i18n/*/LC_MESSAGES/*.mo']},
+</pre>
+<p>Internationalization support is zip safe so your application can be run
+directly from the egg without the need for <tt class="docutils literal"><span class="pre">easy_install</span></tt> to extract it.</p>
+</div>
+<div class="section">
+<h2><a href="#id18" id="plural-forms" name="plural-forms" class="toc-backref">3.6   Plural Forms</a></h2>
+<p>Pylons also defines <tt class="docutils literal"><span class="pre">ungettext()</span></tt> and <tt class="docutils literal"><span class="pre">ngettext()</span></tt> functions which can be imported
+from <tt class="docutils literal"><span class="pre">pylons.i18n</span></tt>. They are designed for internationalizing plural words and can be
+used as follows:</p>
+<textarea name="code" class="python">
+from pylons.i18n import ungettext
+
+ungettext(
+    'There is %(num)d file here',
+    'There are %(num)d files here',
+    n
+) % {'num': n}
+</textarea><p>If you wish to use plural forms in your application you need to add the appropriate
+headers to the <tt class="docutils literal"><span class="pre">.po</span></tt> files for the language you are using. You can read more about
+this at <a href="http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#SEC150" class="reference">http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#SEC150</a></p>
+<p>One thing to keep in mind is that other languages don't have the same
+plural forms as English.  While English only has 2 pulral forms, singular and
+plural, Slovenian has 4!  That means that you must use gettext's
+support for pluralization if you hope to get pluralization right.
+Specifically, the following will not work:</p>
+<textarea name="code" class="python">
+# BAD!
+    if n == 1:
+        msg = _("There was no dog.")
+    else:
+        msg = _("There were no dogs.")
+</textarea></div>
+</div>
+<div class="section">
+<h1><a href="#id19" id="summary" name="summary" class="toc-backref">4   Summary</a></h1>
+<p>Hopefully you now understand the history of Unicode, how to use it in Python
+and where to apply Unicode encoding and decoding in a Pylons application. You
+should also be able to use Unicode in your web app remembering the basic rule to
+use UTF-8 to talk to the world, do the encode and decode at the edge of your
+application.</p>
+<p>You should also be able to internationalize and then localize your application
+using Pylons' support for GNU gettext.</p>
+</div>
+<div class="section">
+<h1><a href="#id20" id="further-reading" name="further-reading" class="toc-backref">5   Further Reading</a></h1>
+<p>This information is based partly on the following articles which can be
+consulted for further information.:</p>
+<p><a href="http://www.joelonsoftware.com/articles/Unicode.html" class="reference">http://www.joelonsoftware.com/articles/Unicode.html</a></p>
+<p><a href="http://www.amk.ca/python/howto/unicode" class="reference">http://www.amk.ca/python/howto/unicode</a></p>
+<p><a href="http://en.wikipedia.org/wiki/Internationalization" class="reference">http://en.wikipedia.org/wiki/Internationalization</a></p>
+<p>Please feel free to report any mistakes to the Pylons mailing list or to the
+author. Any corrections or clarifications would be gratefully received.</p>
+</div>
+
+</div>
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/modtest.html b/lib3/Mako-0.7.3/test/templates/modtest.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/modtest.html
@@ -0,0 +1,1 @@
+this is a test
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/othersubdir/foo.html b/lib3/Mako-0.7.3/test/templates/othersubdir/foo.html
new file mode 100644
diff --git a/lib3/Mako-0.7.3/test/templates/read_unicode.html b/lib3/Mako-0.7.3/test/templates/read_unicode.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/read_unicode.html
@@ -0,0 +1,10 @@
+<% 
+try:
+    file_content = open(path)
+except:
+    raise "Should never execute here"
+doc_content = ''.join(file_content.readlines())
+file_content.close()
+%>
+
+${unicode(doc_content, encoding='utf-8')}
diff --git a/lib3/Mako-0.7.3/test/templates/read_unicode_py3k.html b/lib3/Mako-0.7.3/test/templates/read_unicode_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/read_unicode_py3k.html
@@ -0,0 +1,10 @@
+<% 
+try:
+    file_content = open(path, encoding='utf-8', errors='ignore')
+except:
+    raise "Should never execute here"
+doc_content = ''.join(file_content.readlines())
+file_content.close()
+%>
+
+${bytes(doc_content, encoding='utf-8')}
diff --git a/lib3/Mako-0.7.3/test/templates/runtimeerr.html b/lib3/Mako-0.7.3/test/templates/runtimeerr.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/runtimeerr.html
@@ -0,0 +1,4 @@
+<%
+    print y
+    y = 10
+%>
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/runtimeerr_py3k.html b/lib3/Mako-0.7.3/test/templates/runtimeerr_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/runtimeerr_py3k.html
@@ -0,0 +1,4 @@
+<%
+    print(y)
+    y = 10
+%>
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/subdir/foo/modtest.html.py b/lib3/Mako-0.7.3/test/templates/subdir/foo/modtest.html.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/subdir/foo/modtest.html.py
@@ -0,0 +1,25 @@
+from mako import runtime, filters, cache
+UNDEFINED = runtime.UNDEFINED
+__M_dict_builtin = dict
+__M_locals_builtin = locals
+_magic_number = 5
+_modified_time = 1267565427.799504
+_template_filename='/Users/classic/dev/mako/test/templates/subdir/modtest.html'
+_template_uri='/subdir/modtest.html'
+_template_cache=cache.Cache(__name__, _modified_time)
+_source_encoding=None
+_exports = []
+
+
+def render_body(context,**pageargs):
+    context.caller_stack._push_frame()
+    try:
+        __M_locals = __M_dict_builtin(pageargs=pageargs)
+        __M_writer = context.writer()
+        # SOURCE LINE 1
+        __M_writer('this is a test')
+        return ''
+    finally:
+        context.caller_stack._pop_frame()
+
+
diff --git a/lib3/Mako-0.7.3/test/templates/subdir/incl.html b/lib3/Mako-0.7.3/test/templates/subdir/incl.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/subdir/incl.html
@@ -0,0 +1,2 @@
+
+    this is include 2
diff --git a/lib3/Mako-0.7.3/test/templates/subdir/index.html b/lib3/Mako-0.7.3/test/templates/subdir/index.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/subdir/index.html
@@ -0,0 +1,3 @@
+
+    this is sub index
+    <%include file="incl.html"/>
diff --git a/lib3/Mako-0.7.3/test/templates/subdir/modtest.html b/lib3/Mako-0.7.3/test/templates/subdir/modtest.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/subdir/modtest.html
@@ -0,0 +1,1 @@
+this is a test
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/unicode.html b/lib3/Mako-0.7.3/test/templates/unicode.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/unicode.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/unicode_arguments.html b/lib3/Mako-0.7.3/test/templates/unicode_arguments.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/unicode_arguments.html
@@ -0,0 +1,10 @@
+# coding: utf-8
+
+<%def name="my_def(x)">
+    x is: ${x}
+</%def>
+
+${my_def(u'drôle de petite voix m’a réveillé')}
+<%self:my_def x='drôle de petite voix m’a réveillé'/>
+<%self:my_def x="${u'drôle de petite voix m’a réveillé'}"/>
+<%call expr="my_def(u'drôle de petite voix m’a réveillé')"/>
diff --git a/lib3/Mako-0.7.3/test/templates/unicode_arguments_py3k.html b/lib3/Mako-0.7.3/test/templates/unicode_arguments_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/unicode_arguments_py3k.html
@@ -0,0 +1,10 @@
+# coding: utf-8
+
+<%def name="my_def(x)">
+    x is: ${x}
+</%def>
+
+${my_def('drôle de petite voix m’a réveillé')}
+<%self:my_def x='drôle de petite voix m’a réveillé'/>
+<%self:my_def x="${'drôle de petite voix m’a réveillé'}"/>
+<%call expr="my_def('drôle de petite voix m’a réveillé')"/>
diff --git a/lib3/Mako-0.7.3/test/templates/unicode_code.html b/lib3/Mako-0.7.3/test/templates/unicode_code.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/unicode_code.html
@@ -0,0 +1,7 @@
+## -*- coding: utf-8 -*-
+<%
+    x = u"drôle de petite voix m’a réveillé."
+%>
+% if x==u"drôle de petite voix m’a réveillé.":
+    hi, ${x}
+% endif
diff --git a/lib3/Mako-0.7.3/test/templates/unicode_code_py3k.html b/lib3/Mako-0.7.3/test/templates/unicode_code_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/unicode_code_py3k.html
@@ -0,0 +1,7 @@
+## -*- coding: utf-8 -*-
+<%
+    x = "drôle de petite voix m’a réveillé."
+%>
+% if x=="drôle de petite voix m’a réveillé.":
+    hi, ${x}
+% endif
diff --git a/lib3/Mako-0.7.3/test/templates/unicode_expr.html b/lib3/Mako-0.7.3/test/templates/unicode_expr.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/unicode_expr.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+${u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
diff --git a/lib3/Mako-0.7.3/test/templates/unicode_expr_py3k.html b/lib3/Mako-0.7.3/test/templates/unicode_expr_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/unicode_expr_py3k.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+${"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
diff --git a/lib3/Mako-0.7.3/test/templates/unicode_runtime_error.html b/lib3/Mako-0.7.3/test/templates/unicode_runtime_error.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/unicode_runtime_error.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+<% print 'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »' + int(5/0) %>
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/templates/unicode_syntax_error.html b/lib3/Mako-0.7.3/test/templates/unicode_syntax_error.html
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/templates/unicode_syntax_error.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+<% print 'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! » %>
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/test_ast.py b/lib3/Mako-0.7.3/test/test_ast.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_ast.py
@@ -0,0 +1,334 @@
+import unittest
+
+from mako import ast, exceptions, pyparser, util
+from test import eq_, requires_python_2
+
+exception_kwargs = {
+    'source': '',
+    'lineno': 0,
+    'pos': 0,
+    'filename': ''}
+
+class AstParseTest(unittest.TestCase):
+
+    def test_locate_identifiers(self):
+        """test the location of identifiers in a python code string"""
+        code = """
+a = 10
+b = 5
+c = x * 5 + a + b + q
+(g,h,i) = (1,2,3)
+[u,k,j] = [4,5,6]
+foo.hoho.lala.bar = 7 + gah.blah + u + blah
+for lar in (1,2,3):
+    gh = 5
+    x = 12
+("hello world, ", a, b)
+("Another expr", c)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(
+            parsed.declared_identifiers,
+            set(['a', 'b', 'c', 'g', 'h', 'i', 'u',
+                'k', 'j', 'gh', 'lar', 'x'])
+        )
+        eq_(
+            parsed.undeclared_identifiers,
+            set(['x', 'q', 'foo', 'gah', 'blah'])
+        )
+
+        parsed = ast.PythonCode("x + 5 * (y-z)", **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['x', 'y', 'z'])
+        assert parsed.declared_identifiers == set()
+
+    def test_locate_identifiers_2(self):
+        code = """
+import foobar
+from lala import hoho, yaya
+import bleep as foo
+result = []
+data = get_data()
+for x in data:
+    result.append(x+7)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.undeclared_identifiers, set(['get_data']))
+        eq_(
+            parsed.declared_identifiers,
+            set(['result', 'data', 'x', 'hoho', 'foobar', 'foo', 'yaya'])
+        )
+
+    def test_locate_identifiers_3(self):
+        """test that combination assignment/expressions
+        of the same identifier log the ident as 'undeclared'"""
+        code = """
+x = x + 5
+for y in range(1, y):
+    ("hi",)
+[z for z in range(1, z)]
+(q for q in range (1, q))
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(
+            parsed.undeclared_identifiers,
+            set(['x', 'y', 'z', 'q', 'range'])
+        )
+
+    def test_locate_identifiers_4(self):
+        code = """
+x = 5
+(y, )
+def mydef(mydefarg):
+    print("mda is", mydefarg)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.undeclared_identifiers, set(['y']))
+        eq_(parsed.declared_identifiers, set(['mydef', 'x']))
+
+    def test_locate_identifiers_5(self):
+        code = """
+try:
+    print(x)
+except:
+    print(y)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.undeclared_identifiers, set(['x', 'y']))
+
+    def test_locate_identifiers_6(self):
+        code = """
+def foo():
+    return bar()
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.undeclared_identifiers, set(['bar']))
+
+        code = """
+def lala(x, y):
+    return x, y, z
+print(x)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.undeclared_identifiers, set(['z', 'x']))
+        eq_(parsed.declared_identifiers, set(['lala']))
+
+        code = """
+def lala(x, y):
+    def hoho():
+        def bar():
+            z = 7
+print(z)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.undeclared_identifiers, set(['z']))
+        eq_(parsed.declared_identifiers, set(['lala']))
+
+    def test_locate_identifiers_7(self):
+        code = """
+import foo.bar
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['foo']))
+        eq_(parsed.undeclared_identifiers, set())
+
+    def test_locate_identifiers_8(self):
+        code = """
+class Hi(object):
+    foo = 7
+    def hoho(self):
+        x = 5
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['Hi']))
+        eq_(parsed.undeclared_identifiers, set())
+
+    def test_locate_identifiers_9(self):
+        code = """
+    ",".join([t for t in ("a", "b", "c")])
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['t']))
+        eq_(parsed.undeclared_identifiers, set(['t']))
+
+        code = """
+    [(val, name) for val, name in x]
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['val', 'name']))
+        eq_(parsed.undeclared_identifiers, set(['val', 'name', 'x']))
+
+    def test_locate_identifiers_10(self):
+        code = """
+lambda q: q + 5
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set())
+        eq_(parsed.undeclared_identifiers, set())
+
+    def test_locate_identifiers_11(self):
+        code = """
+def x(q):
+    return q + 5
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['x']))
+        eq_(parsed.undeclared_identifiers, set())
+
+
+    def test_locate_identifiers_12(self):
+        code = """
+def foo():
+    s = 1
+    def bar():
+        t = s
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['foo']))
+        eq_(parsed.undeclared_identifiers, set())
+
+    def test_locate_identifiers_13(self):
+        code = """
+def foo():
+    class Bat(object):
+        pass
+    Bat
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['foo']))
+        eq_(parsed.undeclared_identifiers, set())
+
+    def test_locate_identifiers_14(self):
+        code = """
+def foo():
+    class Bat(object):
+        pass
+    Bat
+
+print(Bat)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['foo']))
+        eq_(parsed.undeclared_identifiers, set(['Bat']))
+
+    @requires_python_2
+    def test_locate_identifiers_15(self):
+        code = """
+def t1((x,y)):
+    return x+5, y+4
+
+t2 = lambda (x,y):(x+5, y+4)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['t1', 't2']))
+        eq_(parsed.undeclared_identifiers, set())
+
+    def test_no_global_imports(self):
+        code = """
+from foo import *
+import x as bar
+"""
+        self.assertRaises(exceptions.CompileException,
+            ast.PythonCode, code, **exception_kwargs)
+
+    def test_python_fragment(self):
+        parsed = ast.PythonFragment("for x in foo:", **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['x']))
+        eq_(parsed.undeclared_identifiers, set(['foo']))
+
+        parsed = ast.PythonFragment("try:", **exception_kwargs)
+
+        if util.py3k:
+            parsed = ast.PythonFragment(
+                        "except MyException as e:", **exception_kwargs)
+        else:
+            parsed = ast.PythonFragment(
+                        "except MyException, e:", **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['e']))
+        eq_(parsed.undeclared_identifiers, set(['MyException']))
+
+    def test_argument_list(self):
+        parsed = ast.ArgumentList("3, 5, 'hi', x+5, "
+                    "context.get('lala')", **exception_kwargs)
+        eq_(parsed.undeclared_identifiers, set(['x', 'context']))
+        eq_([x for x in parsed.args],
+            ["3", "5", "'hi'", "(x + 5)", "context.get('lala')"])
+
+        parsed = ast.ArgumentList("h", **exception_kwargs)
+        eq_(parsed.args, ["h"])
+
+    def test_function_decl(self):
+        """test getting the arguments from a function"""
+        code = "def foo(a, b, c=None, d='hi', e=x, f=y+7):pass"
+        parsed = ast.FunctionDecl(code, **exception_kwargs)
+        eq_(parsed.funcname, 'foo')
+        eq_(parsed.argnames,
+            ['a', 'b', 'c', 'd', 'e', 'f'])
+
+    def test_function_decl_2(self):
+        """test getting the arguments from a function"""
+        code = "def foo(a, b, c=None, *args, **kwargs):pass"
+        parsed = ast.FunctionDecl(code, **exception_kwargs)
+        eq_(parsed.funcname, 'foo')
+        eq_(parsed.argnames,
+            ['a', 'b', 'c', 'args', 'kwargs'])
+
+    def test_expr_generate(self):
+        """test the round trip of expressions to AST back to python source"""
+        x = 1
+        y = 2
+
+        class F(object):
+            def bar(self, a,b):
+                return a + b
+
+        def lala(arg):
+            return "blah" + arg
+
+        local_dict = dict(x=x, y=y, foo=F(), lala=lala)
+
+        code = "str((x+7*y) / foo.bar(5,6)) + lala('ho')"
+        astnode = pyparser.parse(code)
+        newcode = pyparser.ExpressionGenerator(astnode).value()
+        eq_(eval(code, local_dict), eval(newcode, local_dict))
+
+        a = ["one", "two", "three"]
+        hoho = {'somevalue': "asdf"}
+        g = [1, 2, 3, 4, 5]
+        local_dict = dict(a=a, hoho=hoho, g=g)
+        code = "a[2] + hoho['somevalue'] + "\
+                "repr(g[3:5]) + repr(g[3:]) + repr(g[:5])"
+        astnode = pyparser.parse(code)
+        newcode = pyparser.ExpressionGenerator(astnode).value()
+        eq_(eval(code, local_dict), eval(newcode, local_dict))
+
+        local_dict = {'f': lambda: 9, 'x': 7}
+        code = "x+f()"
+        astnode = pyparser.parse(code)
+        newcode = pyparser.ExpressionGenerator(astnode).value()
+        eq_(eval(code, local_dict), eval(newcode, local_dict))
+
+        for code in ["repr({'x':7,'y':18})",
+                        "repr([])",
+                        "repr({})",
+                        "repr([{3:[]}])",
+                        "repr({'x':37*2 + len([6,7,8])})",
+                        "repr([1, 2, {}, {'x':'7'}])",
+                        "repr({'x':-1})", "repr(((1,2,3), (4,5,6)))",
+                        "repr(1 and 2 and 3 and 4)",
+                        "repr(True and False or 55)",
+                        "repr(1 & 2 | 3)",
+                        "repr(3//5)",
+                        "repr(3^5)",
+                        "repr([q.endswith('e') for q in "
+                            "['one', 'two', 'three']])",
+                        "repr([x for x in (5,6,7) if x == 6])",
+                        "repr(not False)"]:
+            local_dict = {}
+            astnode = pyparser.parse(code)
+            newcode = pyparser.ExpressionGenerator(astnode).value()
+            eq_(eval(code, local_dict),
+                eval(newcode, local_dict)
+            )
+
+
+
diff --git a/lib3/Mako-0.7.3/test/test_babelplugin.py b/lib3/Mako-0.7.3/test/test_babelplugin.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_babelplugin.py
@@ -0,0 +1,44 @@
+
+from test import TemplateTest, template_base, skip_if
+
+try:
+    import babel
+    from mako.ext.babelplugin import extract
+except:
+    babel = None
+ 
+import os
+
+
+class ExtractMakoTestCase(TemplateTest):
+    @skip_if(lambda: not babel, 'babel not installed: skipping babelplugin test')
+ 
+    def test_extract(self):
+        mako_tmpl = open(os.path.join(template_base, 'gettext.mako'))
+        messages = list(extract(mako_tmpl, {'_': None, 'gettext': None,
+                                            'ungettext': (1, 2)},
+                                ['TRANSLATOR:'], {}))
+        expected = \
+            [(1, '_', 'Page arg 1', []),
+             (1, '_', 'Page arg 2', []),
+             (10, 'gettext', 'Begin', []),
+             (14, '_', 'Hi there!', ['TRANSLATOR: Hi there!']),
+             (19, '_', 'Hello', []),
+             (22, '_', 'Welcome', []),
+             (25, '_', 'Yo', []),
+             (36, '_', 'The', ['TRANSLATOR: Ensure so and', 'so, thanks']),
+             (36, 'ungettext', ('bunny', 'bunnies', None), []),
+             (41, '_', 'Goodbye', ['TRANSLATOR: Good bye']),
+             (44, '_', 'Babel', []),
+             (45, 'ungettext', ('hella', 'hellas', None), []),
+            (62, '_', 'The', ['TRANSLATOR: Ensure so and', 'so, thanks']),
+            (62, 'ungettext', ('bunny', 'bunnies', None), []),
+            (68, '_', 'Goodbye, really!', ['TRANSLATOR: HTML comment']),
+            (71, '_', 'P.S. byebye', []),
+            (77, '_', 'Top', []),
+            (83, '_', 'foo', []),
+            (83, '_', 'baz', []),
+            (85, '_', 'bar', [])
+             ]
+        self.assertEqual(expected, messages)
+
diff --git a/lib3/Mako-0.7.3/test/test_block.py b/lib3/Mako-0.7.3/test/test_block.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_block.py
@@ -0,0 +1,569 @@
+from mako.template import Template
+from mako.lookup import TemplateLookup
+from mako import exceptions
+from test import TemplateTest, assert_raises, assert_raises_message
+from .util import flatten_result, result_lines
+
+
+
+class BlockTest(TemplateTest):
+    def test_anonymous_block_namespace_raises(self):
+        assert_raises_message(
+            exceptions.CompileException,
+            "Can't put anonymous blocks inside <%namespace>",
+            Template, """
+                <%namespace name="foo">
+                    <%block>
+                        block
+                    </%block>
+                </%namespace>
+            """
+        )
+
+    def test_anonymous_block_in_call(self):
+        template = Template("""
+        
+            <%self:foo x="5">
+                <%block>
+                    this is the block x
+                </%block>
+            </%self:foo>
+            
+            <%def name="foo(x)">
+                foo:
+                ${caller.body()}
+            </%def>
+        """)
+        self._do_test(
+            template,
+            ["foo:", "this is the block x"],
+            filters=result_lines
+        )
+
+    def test_named_block_in_call(self):
+        assert_raises_message(
+            exceptions.CompileException,
+            "Named block 'y' not allowed inside of <%call> tag",
+            Template,"""
+        
+            <%self:foo x="5">
+                <%block name="y">
+                    this is the block
+                </%block>
+            </%self:foo>
+            
+            <%def name="foo(x)">
+                foo:
+                ${caller.body()}
+                ${caller.y()}
+            </%def>
+        """)
+
+    def test_name_collision_blocks_toplevel(self):
+        assert_raises_message(
+            exceptions.CompileException,
+            "%def or %block named 'x' already exists in this template",
+            Template,
+            """
+                <%block name="x">
+                    block
+                </%block>
+                
+                foob 
+                
+                <%block name="x">
+                    block
+                </%block>
+            """
+        )
+
+    def test_name_collision_blocks_nested_block(self):
+        assert_raises_message(
+            exceptions.CompileException,
+            "%def or %block named 'x' already exists in this template",
+            Template,
+            """
+                <%block>
+                <%block name="x">
+                    block
+                </%block>
+                
+                foob 
+                
+                <%block name="x">
+                    block
+                </%block>
+                </%block>
+            """
+        )
+
+    def test_name_collision_blocks_nested_def(self):
+        assert_raises_message(
+            exceptions.CompileException,
+            "Named block 'x' not allowed inside of def 'foo'",
+            Template,
+            """
+                <%def name="foo()">
+                <%block name="x">
+                    block
+                </%block>
+                
+                foob 
+                
+                <%block name="x">
+                    block
+                </%block>
+                </%def>
+            """
+        )
+
+    def test_name_collision_block_def_toplevel(self):
+        assert_raises_message(
+            exceptions.CompileException,
+            "%def or %block named 'x' already exists in this template",
+            Template,
+            """
+                <%block name="x">
+                    block
+                </%block>
+                
+                foob 
+                
+                <%def name="x()">
+                    block
+                </%def>
+            """
+        )
+
+    def test_name_collision_def_block_toplevel(self):
+        assert_raises_message(
+            exceptions.CompileException,
+            "%def or %block named 'x' already exists in this template",
+            Template,
+            """
+                <%def name="x()">
+                    block
+                </%def>
+
+                foob 
+                
+                <%block name="x">
+                    block
+                </%block>
+                
+            """
+        )
+
+    def test_named_block_renders(self):
+        template = Template("""
+            above
+            <%block name="header">
+                the header
+            </%block>
+            below
+        """)
+        self._do_test(template, ["above", "the header", "below"], 
+                filters=result_lines)
+
+    def test_inherited_block_no_render(self):
+        l = TemplateLookup()
+        l.put_string("index",
+            """
+                <%inherit file="base"/>
+                <%block name="header">
+                    index header
+                </%block>
+            """
+        )
+        l.put_string("base","""
+            above
+            <%block name="header">
+                the header
+            </%block>
+            
+            ${next.body()}
+            below
+        """)
+        self._do_test(l.get_template("index"), 
+                ["above", "index header", "below"], 
+                filters=result_lines)
+
+    def test_no_named_in_def(self):
+        assert_raises_message(
+            exceptions.CompileException,
+            "Named block 'y' not allowed inside of def 'q'",
+            Template,
+            """
+            <%def name="q()">
+                <%block name="y">
+                </%block>
+            </%def>
+        """)
+
+    def test_inherited_block_nested_both(self):
+        l = TemplateLookup()
+        l.put_string("index",
+            """
+                <%inherit file="base"/>
+                <%block name="title">
+                    index title
+                </%block>
+                
+                <%block name="header">
+                    index header
+                    ${parent.header()}
+                </%block>
+            """
+        )
+        l.put_string("base","""
+            above
+            <%block name="header">
+                base header
+                <%block name="title">
+                    the title
+                </%block>
+            </%block>
+            
+            ${next.body()}
+            below
+        """)
+        self._do_test(l.get_template("index"), 
+                ["above", "index header", "base header", "index title", "below"], 
+                filters=result_lines)
+
+    def test_inherited_block_nested_inner_only(self):
+        l = TemplateLookup()
+        l.put_string("index",
+            """
+                <%inherit file="base"/>
+                <%block name="title">
+                    index title
+                </%block>
+                
+            """
+        )
+        l.put_string("base","""
+            above
+            <%block name="header">
+                base header
+                <%block name="title">
+                    the title
+                </%block>
+            </%block>
+            
+            ${next.body()}
+            below
+        """)
+        self._do_test(l.get_template("index"), 
+                ["above", "base header", "index title", "below"], 
+                filters=result_lines)
+
+    def test_noninherited_block_no_render(self):
+        l = TemplateLookup()
+        l.put_string("index",
+            """
+                <%inherit file="base"/>
+                <%block name="some_thing">
+                    some thing
+                </%block>
+            """
+        )
+        l.put_string("base","""
+            above
+            <%block name="header">
+                the header
+            </%block>
+            
+            ${next.body()}
+            below
+        """)
+        self._do_test(l.get_template("index"), 
+                ["above", "the header", "some thing", "below"], 
+                filters=result_lines)
+
+    def test_no_conflict_nested_one(self):
+        l = TemplateLookup()
+        l.put_string("index",
+            """
+                <%inherit file="base"/>
+                <%block>
+                    <%block name="header">
+                        inner header
+                    </%block>
+                </%block>
+            """
+        )
+        l.put_string("base","""
+            above
+            <%block name="header">
+                the header
+            </%block>
+            
+            ${next.body()}
+            below
+        """)
+        self._do_test(l.get_template("index"), 
+                ["above", "inner header", "below"], 
+                filters=result_lines)
+
+    def test_nested_dupe_names_raise(self):
+        assert_raises_message(
+            exceptions.CompileException,
+            "%def or %block named 'header' already exists in this template.",
+            Template,
+            """
+                <%inherit file="base"/>
+                <%block name="header">
+                    <%block name="header">
+                        inner header
+                    </%block>
+                </%block>
+            """
+        )
+
+    def test_two_levels_one(self):
+        l = TemplateLookup()
+        l.put_string("index",
+            """
+                <%inherit file="middle"/>
+                <%block name="header">
+                    index header
+                </%block>
+                <%block>
+                    index anon
+                </%block>
+            """
+        )
+        l.put_string("middle", """
+            <%inherit file="base"/>
+            <%block>
+                middle anon
+            </%block>
+            ${next.body()}
+        """)
+        l.put_string("base","""
+            above
+            <%block name="header">
+                the header
+            </%block>
+            
+            ${next.body()}
+            below
+        """)
+        self._do_test(l.get_template("index"), 
+                ["above", "index header", "middle anon", 
+                "index anon", "below"], 
+                filters=result_lines)
+
+    def test_filter(self):
+        template = Template("""
+            <%block filter="h">
+                <html>
+            </%block>
+        """)
+        self._do_test(template, ['<html>'], 
+                    filters=result_lines)
+
+    def test_anon_in_named(self):
+        template = Template("""
+            <%block name="x">
+                outer above
+                <%block>
+                    inner
+                </%block>
+                outer below
+            </%block>
+        """)
+        self._test_block_in_block(template)
+
+    def test_named_in_anon(self):
+        template = Template("""
+            <%block>
+                outer above
+                <%block name="x">
+                    inner
+                </%block>
+                outer below
+            </%block>
+        """)
+        self._test_block_in_block(template)
+
+    def test_anon_in_anon(self):
+        template = Template("""
+            <%block>
+                outer above
+                <%block>
+                    inner
+                </%block>
+                outer below
+            </%block>
+        """)
+        self._test_block_in_block(template)
+
+    def test_named_in_named(self):
+        template = Template("""
+            <%block name="x">
+                outer above
+                <%block name="y">
+                    inner
+                </%block>
+                outer below
+            </%block>
+        """)
+        self._test_block_in_block(template)
+
+    def _test_block_in_block(self, template):
+        self._do_test(template, 
+            ["outer above", "inner", "outer below"],
+            filters=result_lines
+        )
+
+    def test_iteration(self):
+        t = Template("""
+            % for i in (1, 2, 3):
+                <%block>${i}</%block>
+            % endfor
+        """)
+        self._do_test(t, 
+            ["1", "2", "3"],
+            filters=result_lines
+        )
+
+    def test_conditional(self):
+        t = Template("""
+            % if True:
+                <%block>true</%block>
+            % endif
+
+            % if False:
+                <%block>false</%block>
+            % endif
+        """)
+        self._do_test(t, 
+            ["true"],
+            filters=result_lines
+        )
+
+    def test_block_overridden_by_def(self):
+        l = TemplateLookup()
+        l.put_string("index",
+            """
+                <%inherit file="base"/>
+                <%def name="header()">
+                    inner header
+                </%def>
+            """
+        )
+        l.put_string("base","""
+            above
+            <%block name="header">
+                the header
+            </%block>
+            
+            ${next.body()}
+            below
+        """)
+        self._do_test(l.get_template("index"), 
+                ["above", "inner header", "below"], 
+                filters=result_lines)
+
+    def test_def_overridden_by_block(self):
+        l = TemplateLookup()
+        l.put_string("index",
+            """
+                <%inherit file="base"/>
+                <%block name="header">
+                    inner header
+                </%block>
+            """
+        )
+        l.put_string("base","""
+            above
+            ${self.header()}
+            <%def name="header()">
+                the header
+            </%def>
+            
+            ${next.body()}
+            below
+        """)
+        self._do_test(l.get_template("index"), 
+                ["above", "inner header", "below"], 
+                filters=result_lines)
+
+    def test_block_args(self):
+        l = TemplateLookup()
+        l.put_string("caller", """
+        
+            <%include file="callee" args="val1='3', val2='4'"/>
+            
+        """)
+        l.put_string("callee", """
+            <%page args="val1, val2"/>
+            <%block name="foob" args="val1, val2">
+                foob, ${val1}, ${val2}
+            </%block>
+        """)
+        self._do_test(
+            l.get_template("caller"),
+            ['foob, 3, 4'],
+            filters=result_lines
+        )
+
+    def test_block_variables_contextual(self):
+        t = Template("""            
+            <%block name="foob" >
+                foob, ${val1}, ${val2}
+            </%block>
+        """)
+        self._do_test(
+            t,
+            ['foob, 3, 4'],
+            template_args={'val1':3, 'val2':4},
+            filters=result_lines
+        )
+
+    def test_block_args_contextual(self):
+        t = Template("""            
+            <%page args="val1"/>
+            <%block name="foob" args="val1">
+                foob, ${val1}, ${val2}
+            </%block>
+        """)
+        self._do_test(
+            t,
+            ['foob, 3, 4'],
+            template_args={'val1':3, 'val2':4},
+            filters=result_lines
+        )
+
+    def test_block_pageargs_contextual(self):
+        t = Template("""            
+            <%block name="foob">
+                foob, ${pageargs['val1']}, ${pageargs['val2']}
+            </%block>
+        """)
+        self._do_test(
+            t,
+            ['foob, 3, 4'],
+            template_args={'val1':3, 'val2':4},
+            filters=result_lines
+        )
+
+    def test_block_pageargs(self):
+        l = TemplateLookup()
+        l.put_string("caller", """
+        
+            <%include file="callee" args="val1='3', val2='4'"/>
+            
+        """)
+        l.put_string("callee", """
+            <%block name="foob">
+                foob, ${pageargs['val1']}, ${pageargs['val2']}
+            </%block>
+        """)
+        self._do_test(
+            l.get_template("caller"),
+            ['foob, 3, 4'],
+            filters=result_lines
+        )
\ No newline at end of file
diff --git a/lib3/Mako-0.7.3/test/test_cache.py b/lib3/Mako-0.7.3/test/test_cache.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_cache.py
@@ -0,0 +1,557 @@
+from mako.template import Template
+from mako.lookup import TemplateLookup
+from mako import lookup
+import shutil, unittest, os, time
+from .util import result_lines
+from test import TemplateTest, template_base, module_base
+from test import eq_
+
+try:
+    import beaker
+    import beaker.cache
+except:
+    from nose import SkipTest
+    raise SkipTest("Beaker is required for these tests.")
+
+from mako.cache import register_plugin, CacheImpl
+
+class MockCacheImpl(CacheImpl):
+    realcacheimpl = None
+
+    def __init__(self, cache):
+        self.cache = cache
+        use_beaker = self.cache.\
+                    template.cache_args.\
+                    get('use_beaker', True)
+        if use_beaker:
+            self.realcacheimpl = cache._load_impl("beaker")
+
+    def get_or_create(self, key, creation_function, **kw):
+        self.key = key
+        self.kwargs = kw.copy()
+        if self.realcacheimpl:
+            return self.realcacheimpl.\
+                    get_or_create(key, creation_function, **kw)
+        else:
+            return creation_function()
+
+    def put(self, key, value, **kw):
+        self.key = key
+        self.kwargs = kw.copy()
+        if self.realcacheimpl:
+            self.realcacheimpl.put(key, value, **kw)
+
+    def get(self, key, **kw):
+        self.key = key
+        self.kwargs = kw.copy()
+        if self.realcacheimpl:
+            return self.realcacheimpl.get(key, **kw)
+
+    def invalidate(self, key, **kw):
+        self.key = key
+        self.kwargs = kw.copy()
+        if self.realcacheimpl:
+            self.realcacheimpl.invalidate(key, **kw)
+
+
+register_plugin("mock", __name__, "MockCacheImpl")
+
+class BeakerCacheTest(TemplateTest):
+    def _regions(self):
+        return beaker.cache.CacheManager(
+            cache_regions = {
+                'short':{
+                    'expire':1,
+                    'type':'memory'
+                },
+                'long':{
+                    'expire':60,
+                    'type':'memory'
+                }
+            }
+        )
+
+    def test_region(self):
+        t = Template("""
+            <%block name="foo" cached="True" cache_region="short">
+                short term ${x}
+            </%block>
+            <%block name="bar" cached="True" cache_region="long">
+                long term ${x}
+            </%block>
+            <%block name="lala">
+                none ${x}
+            </%block>
+        """, cache_args={"manager":self._regions()})
+
+        r1 = result_lines(t.render(x=5))
+        time.sleep(2)
+        r2 = result_lines(t.render(x=6))
+        r3 = result_lines(t.render(x=7))
+        eq_(r1, ["short term 5", "long term 5", "none 5"])
+        eq_(r2, ["short term 6", "long term 5", "none 6"])
+        eq_(r3, ["short term 6", "long term 5", "none 7"])
+
+class CacheTest(TemplateTest):
+    def _install_mock_cache(self, template):
+        template.cache_impl = 'mock'
+        return template.cache.impl
+
+    def test_def(self):
+        t = Template("""
+        <%!
+            callcount = [0]
+        %>
+        <%def name="foo()" cached="True">
+            this is foo
+            <%
+            callcount[0] += 1
+            %>
+        </%def>
+
+        ${foo()}
+        ${foo()}
+        ${foo()}
+        callcount: ${callcount}
+""")
+        m = self._install_mock_cache(t)
+        assert result_lines(t.render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        assert m.kwargs == {}
+
+    def test_cache_enable(self):
+        t = Template("""
+            <%!
+                callcount = [0]
+            %>
+            <%def name="foo()" cached="True">
+                <% callcount[0] += 1 %>
+            </%def>
+            ${foo()}
+            ${foo()}
+            callcount: ${callcount}
+        """, cache_enabled=False)
+        m = self._install_mock_cache(t)
+
+        eq_(t.render().strip(), "callcount: [2]")
+
+    def test_nested_def(self):
+        t = Template("""
+        <%!
+            callcount = [0]
+        %>
+        <%def name="foo()">
+            <%def name="bar()" cached="True">
+                this is foo
+                <%
+                callcount[0] += 1
+                %>
+            </%def>
+            ${bar()}
+        </%def>
+
+        ${foo()}
+        ${foo()}
+        ${foo()}
+        callcount: ${callcount}
+""")
+        m = self._install_mock_cache(t)
+        assert result_lines(t.render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        assert m.kwargs == {}
+
+    def test_page(self):
+        t = Template("""
+        <%!
+            callcount = [0]
+        %>
+        <%page cached="True"/>
+        this is foo
+        <%
+        callcount[0] += 1
+        %>
+        callcount: ${callcount}
+""")
+        m = self._install_mock_cache(t)
+        t.render()
+        t.render()
+        assert result_lines(t.render()) == [
+            "this is foo",
+            "callcount: [1]"
+        ]
+        assert m.kwargs == {}
+
+    def test_dynamic_key_with_context(self):
+        t = Template("""
+            <%block name="foo" cached="True" cache_key="${mykey}">
+                some block
+            </%block>
+        """)
+        m = self._install_mock_cache(t)
+        t.render(mykey="thekey")
+        t.render(mykey="thekey")
+        eq_(
+            result_lines(t.render(mykey="thekey")),
+            ["some block"]
+        )
+        eq_(m.key, "thekey")
+
+        t = Template("""
+            <%def name="foo()" cached="True" cache_key="${mykey}">
+                some def
+            </%def>
+            ${foo()}
+        """)
+        m = self._install_mock_cache(t)
+        t.render(mykey="thekey")
+        t.render(mykey="thekey")
+        eq_(
+            result_lines(t.render(mykey="thekey")),
+            ["some def"]
+        )
+        eq_(m.key, "thekey")
+
+
+    def test_dynamic_key_with_funcargs(self):
+        t = Template("""
+            <%def name="foo(num=5)" cached="True" cache_key="foo_${str(num)}">
+             hi
+            </%def>
+
+            ${foo()}
+        """)
+        m = self._install_mock_cache(t)
+        t.render()
+        t.render()
+        assert result_lines(t.render()) == ['hi']
+        assert m.key == "foo_5"
+
+        t = Template("""
+            <%def name="foo(*args, **kwargs)" cached="True" cache_key="foo_${kwargs['bar']}">
+             hi
+            </%def>
+
+            ${foo(1, 2, bar='lala')}
+        """)
+        m = self._install_mock_cache(t)
+        t.render()
+        assert result_lines(t.render()) == ['hi']
+        assert m.key == "foo_lala"
+
+        t = Template('''
+        <%page args="bar='hi'" cache_key="foo_${bar}" cached="True"/>
+         hi
+        ''')
+        m = self._install_mock_cache(t)
+        t.render()
+        assert result_lines(t.render()) == ['hi']
+        assert m.key == "foo_hi"
+
+
+    def test_dynamic_key_with_imports(self):
+        lookup = TemplateLookup()
+        lookup.put_string("foo.html", """
+        <%!
+            callcount = [0]
+        %>
+        <%namespace file="ns.html" import="*"/>
+        <%page cached="True" cache_key="${foo}"/>
+        this is foo
+        <%
+        callcount[0] += 1
+        %>
+        callcount: ${callcount}
+""")
+        lookup.put_string("ns.html", """""")
+        t = lookup.get_template("foo.html")
+        m = self._install_mock_cache(t)
+        t.render(foo='somekey')
+        t.render(foo='somekey')
+        assert result_lines(t.render(foo='somekey')) == [
+            "this is foo",
+            "callcount: [1]"
+        ]
+        assert m.kwargs == {}
+
+    def test_fileargs_implicit(self):
+        l = lookup.TemplateLookup(module_directory=module_base)
+        l.put_string("test","""
+                <%!
+                    callcount = [0]
+                %>
+                <%def name="foo()" cached="True" cache_type='dbm'>
+                    this is foo
+                    <%
+                    callcount[0] += 1
+                    %>
+                </%def>
+
+                ${foo()}
+                ${foo()}
+                ${foo()}
+                callcount: ${callcount}
+        """)
+
+        m = self._install_mock_cache(l.get_template('test'))
+        assert result_lines(l.get_template('test').render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        eq_(m.kwargs, {'type':'dbm'})
+
+    def test_fileargs_deftag(self):
+        t = Template("""
+        <%%!
+            callcount = [0]
+        %%>
+        <%%def name="foo()" cached="True" cache_type='file' cache_dir='%s'>
+            this is foo
+            <%%
+            callcount[0] += 1
+            %%>
+        </%%def>
+
+        ${foo()}
+        ${foo()}
+        ${foo()}
+        callcount: ${callcount}
+""" % module_base)
+        m = self._install_mock_cache(t)
+        assert result_lines(t.render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        assert m.kwargs == {'type':'file','dir':module_base}
+
+    def test_fileargs_pagetag(self):
+        t = Template("""
+        <%%page cache_dir='%s' cache_type='dbm'/>
+        <%%!
+            callcount = [0]
+        %%>
+        <%%def name="foo()" cached="True">
+            this is foo
+            <%%
+            callcount[0] += 1
+            %%>
+        </%%def>
+
+        ${foo()}
+        ${foo()}
+        ${foo()}
+        callcount: ${callcount}
+""" % module_base)
+        m = self._install_mock_cache(t)
+        assert result_lines(t.render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        eq_(m.kwargs, {'dir':module_base, 'type':'dbm'})
+
+    def test_args_complete(self):
+        t = Template("""
+        <%%def name="foo()" cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'>
+            this is foo
+        </%%def>
+
+        ${foo()}
+""" % module_base)
+        m = self._install_mock_cache(t)
+        t.render()
+        eq_(m.kwargs, {'dir':module_base, 'type':'file', 'timeout':30})
+
+        t2 = Template("""
+        <%%page cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'/>
+        hi
+        """ % module_base)
+        m = self._install_mock_cache(t2)
+        t2.render()
+        eq_(m.kwargs, {'dir':module_base, 'type':'file', 'timeout':30})
+
+    def test_fileargs_lookup(self):
+        l = lookup.TemplateLookup(cache_dir=module_base, cache_type='file')
+        l.put_string("test","""
+                <%!
+                    callcount = [0]
+                %>
+                <%def name="foo()" cached="True">
+                    this is foo
+                    <%
+                    callcount[0] += 1
+                    %>
+                </%def>
+
+                ${foo()}
+                ${foo()}
+                ${foo()}
+                callcount: ${callcount}
+        """)
+
+        t = l.get_template('test')
+        m = self._install_mock_cache(t)
+        assert result_lines(l.get_template('test').render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        eq_(m.kwargs, {'dir':module_base, 'type':'file'})
+
+    def test_buffered(self):
+        t = Template("""
+        <%!
+            def a(text):
+                return "this is a " + text.strip()
+        %>
+        ${foo()}
+        ${foo()}
+        <%def name="foo()" cached="True" buffered="True">
+            this is a test
+        </%def>
+        """, buffer_filters=["a"])
+        assert result_lines(t.render()) == ["this is a this is a test", "this is a this is a test"]
+
+    def test_load_from_expired(self):
+        """test that the cache callable can be called safely after the
+        originating template has completed rendering.
+
+        """
+        t = Template("""
+        ${foo()}
+        <%def name="foo()" cached="True" cache_timeout="2">
+            foo
+        </%def>
+        """)
+
+        x1 = t.render()
+        time.sleep(3)
+        x2 = t.render()
+        assert x1.strip() == x2.strip() == "foo"
+
+    def test_cache_uses_current_context(self):
+        t = Template("""
+        ${foo()}
+        <%def name="foo()" cached="True" cache_timeout="2">
+            foo: ${x}
+        </%def>
+        """)
+
+        x1 = t.render(x=1)
+        time.sleep(3)
+        x2 = t.render(x=2)
+        eq_(x1.strip(), "foo: 1")
+        eq_(x2.strip(), "foo: 2")
+
+    def test_namespace_access(self):
+        t = Template("""
+            <%def name="foo(x)" cached="True">
+                foo: ${x}
+            </%def>
+
+            <%
+                foo(1)
+                foo(2)
+                local.cache.invalidate_def('foo')
+                foo(3)
+                foo(4)
+            %>
+        """)
+        assert result_lines(t.render()) == ['foo: 1', 'foo: 1', 'foo: 3', 'foo: 3']
+
+    def test_lookup(self):
+        l = TemplateLookup(cache_impl='mock')
+        l.put_string("x", """
+            <%page cached="True" />
+            ${y}
+        """)
+        t = l.get_template("x")
+        assert result_lines(t.render(y=5)) == ["5"]
+        assert result_lines(t.render(y=7)) == ["5"]
+        assert isinstance(t.cache.impl, MockCacheImpl)
+
+    def test_invalidate(self):
+        t = Template("""
+            <%%def name="foo()" cached="True">
+                foo: ${x}
+            </%%def>
+
+            <%%def name="bar()" cached="True" cache_type='dbm' cache_dir='%s'>
+                bar: ${x}
+            </%%def>
+            ${foo()} ${bar()}
+        """ % module_base)
+        assert result_lines(t.render(x=1)) == ["foo: 1", "bar: 1"]
+        assert result_lines(t.render(x=2)) == ["foo: 1", "bar: 1"]
+        t.cache.invalidate_def('foo')
+        assert result_lines(t.render(x=3)) == ["foo: 3", "bar: 1"]
+        t.cache.invalidate_def('bar')
+        assert result_lines(t.render(x=4)) == ["foo: 3", "bar: 4"]
+
+        t = Template("""
+            <%%page cached="True" cache_type="dbm" cache_dir="%s"/>
+
+            page: ${x}
+        """ % module_base)
+        assert result_lines(t.render(x=1)) == ["page: 1"]
+        assert result_lines(t.render(x=2)) == ["page: 1"]
+        t.cache.invalidate_body()
+        assert result_lines(t.render(x=3)) == ["page: 3"]
+        assert result_lines(t.render(x=4)) == ["page: 3"]
+
+    def test_custom_args_def(self):
+        t = Template("""
+            <%def name="foo()" cached="True" cache_region="myregion"
+                    cache_timeout="50" cache_foo="foob">
+            </%def>
+            ${foo()}
+        """, cache_args={'use_beaker':False})
+        m = self._install_mock_cache(t)
+        t.render()
+        eq_(m.kwargs, {'use_beaker':False,'region':'myregion', 'timeout':50, 'foo':'foob'})
+
+    def test_custom_args_block(self):
+        t = Template("""
+            <%block name="foo" cached="True" cache_region="myregion"
+                    cache_timeout="50" cache_foo="foob">
+            </%block>
+        """, cache_args={'use_beaker':False})
+        m = self._install_mock_cache(t)
+        t.render()
+        eq_(m.kwargs, {'use_beaker':False, 'region':'myregion', 'timeout':50, 'foo':'foob'})
+
+    def test_custom_args_page(self):
+        t = Template("""
+            <%page cached="True" cache_region="myregion"
+                    cache_timeout="50" cache_foo="foob"/>
+        """, cache_args={'use_beaker':False})
+        m = self._install_mock_cache(t)
+        t.render()
+        eq_(m.kwargs, {'use_beaker':False, 'region':'myregion', 'timeout':50, 'foo':'foob'})
+
+    def test_pass_context(self):
+        t = Template("""
+            <%page cached="True"/>
+        """)
+        m = self._install_mock_cache(t)
+        t.render()
+        assert 'context' not in m.kwargs
+
+        m.pass_context = True
+        t.render(x="bar")
+        assert 'context' in m.kwargs
+        assert m.kwargs['context'].get('x') == 'bar'
+
diff --git a/lib3/Mako-0.7.3/test/test_call.py b/lib3/Mako-0.7.3/test/test_call.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_call.py
@@ -0,0 +1,515 @@
+from mako.template import Template
+from mako import util
+from .util import result_lines, flatten_result
+from test import TemplateTest, eq_
+
+class CallTest(TemplateTest):
+    def test_call(self):
+        t = Template("""
+        <%def name="foo()">
+            hi im foo ${caller.body(y=5)}
+        </%def>
+ 
+        <%call expr="foo()" args="y, **kwargs">
+            this is the body, y is ${y}
+        </%call>
+""")
+        assert result_lines(t.render()) == ['hi im foo', 'this is the body, y is 5']
+
+
+    def test_compound_call(self):
+        t = Template("""
+
+        <%def name="bar()">
+            this is bar
+        </%def>
+ 
+        <%def name="comp1()">
+            this comp1 should not be called
+        </%def>
+ 
+        <%def name="foo()">
+            foo calling comp1: ${caller.comp1(x=5)}
+            foo calling body: ${caller.body()}
+        </%def>
+ 
+        <%call expr="foo()">
+            <%def name="comp1(x)">
+                this is comp1, ${x}
+            </%def>
+            this is the body, ${comp1(6)}
+        </%call>
+        ${bar()}
+
+""")
+        assert result_lines(t.render()) == ['foo calling comp1:', 'this is comp1, 5', 'foo calling body:', 'this is the body,', 'this is comp1, 6', 'this is bar']
+
+    def test_new_syntax(self):
+        """test foo:bar syntax, including multiline args and expression eval."""
+ 
+        # note the trailing whitespace in the bottom ${} expr, need to strip
+        # that off < python 2.7
+ 
+        t = Template("""
+            <%def name="foo(x, y, q, z)">
+                ${x}
+                ${y}
+                ${q}
+                ${",".join("%s->%s" % (a, b) for a, b in z)}
+            </%def>
+ 
+            <%self:foo x="this is x" y="${'some ' + 'y'}" q="
+                this
+                is
+                q"
+ 
+                z="${[
+                (1, 2),
+                (3, 4),
+                (5, 6)
+            ]
+ 
+            }"/>
+        """)
+ 
+        eq_(
+            result_lines(t.render()),
+             ['this is x', 'some y', 'this', 'is', 'q', '1->2,3->4,5->6']
+        )
+ 
+    def test_ccall_caller(self):
+        t = Template("""
+        <%def name="outer_func()">
+        OUTER BEGIN
+            <%call expr="caller.inner_func()">
+                INNER CALL
+            </%call>
+        OUTER END
+        </%def>
+
+        <%call expr="outer_func()">
+            <%def name="inner_func()">
+                INNER BEGIN
+                ${caller.body()}
+                INNER END
+            </%def>
+        </%call>
+
+        """)
+        #print t.code
+        assert result_lines(t.render()) == [
+            "OUTER BEGIN",
+            "INNER BEGIN",
+            "INNER CALL",
+            "INNER END",
+            "OUTER END",
+        ]
+ 
+    def test_stack_pop(self):
+        t = Template("""
+        <%def name="links()" buffered="True">
+           Some links
+        </%def>
+
+        <%def name="wrapper(links)">
+           <h1>${caller.body()}</h1>
+           ${links}
+        </%def>
+
+        ## links() pushes a stack frame on.  when complete,
+        ## 'nextcaller' must be restored
+        <%call expr="wrapper(links())">
+           Some title
+        </%call>
+
+        """)
+
+        assert result_lines(t.render()) == [
+        "<h1>",
+        "Some title",
+        "</h1>",
+        "Some links"
+        ]
+ 
+    def test_conditional_call(self):
+        """test that 'caller' is non-None only if the immediate <%def> was called via <%call>"""
+
+        t = Template("""
+        <%def name="a()">
+        % if caller:
+        ${ caller.body() } \\
+        % endif
+        AAA
+        ${ b() }
+        </%def>
+
+        <%def name="b()">
+        % if caller:
+        ${ caller.body() } \\
+        % endif
+        BBB
+        ${ c() }
+        </%def>
+
+        <%def name="c()">
+        % if caller:
+        ${ caller.body() } \\
+        % endif
+        CCC
+        </%def>
+
+        <%call expr="a()">
+        CALL
+        </%call>
+
+        """)
+        assert result_lines(t.render()) == [
+            "CALL",
+            "AAA",
+            "BBB",
+            "CCC"
+        ]
+ 
+    def test_chained_call(self):
+        """test %calls that are chained through their targets"""
+        t = Template("""
+            <%def name="a()">
+                this is a. 
+                <%call expr="b()">
+                    this is a's ccall.  heres my body: ${caller.body()}
+                </%call>
+            </%def>
+            <%def name="b()">
+                this is b.  heres  my body: ${caller.body()}
+                whats in the body's caller's body ?
+                ${context.caller_stack[-2].body()}
+            </%def>
+ 
+            <%call expr="a()">
+                heres the main templ call
+            </%call>
+ 
+""")
+        assert result_lines(t.render()) == [
+            'this is a.',
+            'this is b. heres my body:',
+            "this is a's ccall. heres my body:",
+            'heres the main templ call',
+            "whats in the body's caller's body ?",
+            'heres the main templ call'
+        ]
+
+    def test_nested_call(self):
+        """test %calls that are nested inside each other"""
+        t = Template("""
+            <%def name="foo()">
+                ${caller.body(x=10)}
+            </%def>
+
+            x is ${x}
+            <%def name="bar()">
+                bar: ${caller.body()}
+            </%def>
+
+            <%call expr="foo()" args="x">
+                this is foo body: ${x}
+
+                <%call expr="bar()">
+                    this is bar body: ${x}
+                </%call>
+            </%call>
+""")
+        assert result_lines(t.render(x=5)) == [
+            "x is 5",
+            "this is foo body: 10",
+            "bar:",
+            "this is bar body: 10"
+        ]
+ 
+    def test_nested_call_2(self):
+        t = Template("""
+            x is ${x}
+            <%def name="foo()">
+                ${caller.foosub(x=10)}
+            </%def>
+
+            <%def name="bar()">
+                bar: ${caller.barsub()}
+            </%def>
+
+            <%call expr="foo()">
+                <%def name="foosub(x)">
+                this is foo body: ${x}
+ 
+                <%call expr="bar()">
+                    <%def name="barsub()">
+                    this is bar body: ${x}
+                    </%def>
+                </%call>
+ 
+                </%def>
+
+            </%call>
+""")
+        assert result_lines(t.render(x=5)) == [
+            "x is 5",
+            "this is foo body: 10",
+            "bar:",
+            "this is bar body: 10"
+        ]
+
+    def test_nested_call_3(self):
+        template = Template('''\
+        <%def name="A()">
+          ${caller.body()}
+        </%def>
+
+        <%def name="B()">
+          ${caller.foo()}
+        </%def>
+
+        <%call expr="A()">
+          <%call expr="B()">
+            <%def name="foo()">
+              foo
+            </%def>
+          </%call>
+        </%call>
+
+        ''')
+        assert flatten_result(template.render()) == "foo"
+ 
+    def test_nested_call_4(self):
+        base = """
+        <%def name="A()">
+        A_def
+        ${caller.body()}
+        </%def>
+
+        <%def name="B()">
+        B_def
+        ${caller.body()}
+        </%def>
+        """
+
+        template = Template(base + """
+        <%def name="C()">
+         C_def
+         <%self:B>
+           <%self:A>
+              A_body
+           </%self:A>
+            B_body
+           ${caller.body()}
+         </%self:B>
+        </%def>
+
+        <%self:C>
+        C_body
+        </%self:C>
+        """)
+
+        eq_(
+            flatten_result(template.render()),
+            "C_def B_def A_def A_body B_body C_body"
+        )
+
+        template = Template(base + """
+        <%def name="C()">
+         C_def
+         <%self:B>
+            B_body
+           ${caller.body()}
+           <%self:A>
+              A_body
+           </%self:A>
+         </%self:B>
+        </%def>
+
+        <%self:C>
+        C_body
+        </%self:C>
+        """)
+
+        eq_(
+            flatten_result(template.render()),
+            "C_def B_def B_body C_body A_def A_body"
+        )
+
+    def test_chained_call_in_nested(self):
+        t = Template("""
+            <%def name="embedded()">
+            <%def name="a()">
+                this is a. 
+                <%call expr="b()">
+                    this is a's ccall.  heres my body: ${caller.body()}
+                </%call>
+            </%def>
+            <%def name="b()">
+                this is b.  heres  my body: ${caller.body()}
+                whats in the body's caller's body ? ${context.caller_stack[-2].body()}
+            </%def>
+
+            <%call expr="a()">
+                heres the main templ call
+            </%call>
+            </%def>
+            ${embedded()}
+""")
+        #print t.code
+        #print result_lines(t.render())
+        assert result_lines(t.render()) == [
+            'this is a.',
+            'this is b. heres my body:',
+            "this is a's ccall. heres my body:",
+            'heres the main templ call',
+            "whats in the body's caller's body ?",
+            'heres the main templ call'
+        ]
+ 
+    def test_call_in_nested(self):
+        t = Template("""
+            <%def name="a()">
+                this is a ${b()}
+                <%def name="b()">
+                    this is b
+                    <%call expr="c()">
+                        this is the body in b's call
+                    </%call>
+                </%def>
+                <%def name="c()">
+                    this is c: ${caller.body()}
+                </%def>
+            </%def>
+        ${a()}
+""")
+        assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call"]
+
+    def test_composed_def(self):
+        t = Template("""
+            <%def name="f()"><f>${caller.body()}</f></%def>
+            <%def name="g()"><g>${caller.body()}</g></%def>
+            <%def name="fg()">
+                <%self:f><%self:g>${caller.body()}</%self:g></%self:f>
+            </%def>
+            <%self:fg>fgbody</%self:fg>
+            """)
+        assert result_lines(t.render()) == ['<f><g>fgbody</g></f>']
+
+    def test_regular_defs(self):
+        t = Template("""
+        <%!
+            @runtime.supports_caller
+            def a(context):
+                context.write("this is a")
+                if context['caller']:
+                    context['caller'].body()
+                context.write("a is done")
+                return ''
+        %>
+ 
+        <%def name="b()">
+            this is b
+            our body: ${caller.body()}
+            ${a(context)}
+        </%def>
+        test 1
+        <%call expr="a(context)">
+            this is the body
+        </%call>
+        test 2
+        <%call expr="b()">
+            this is the body
+        </%call>
+        test 3
+        <%call expr="b()">
+            this is the body
+            <%call expr="b()">
+                this is the nested body
+            </%call>
+        </%call>
+
+
+        """) 
+        #print t.code
+        assert result_lines(t.render()) == [
+            "test 1",
+            "this is a",
+            "this is the body",
+            "a is done",
+            "test 2",
+            "this is b",
+            "our body:",
+            "this is the body",
+            "this is aa is done",
+            "test 3",
+            "this is b",
+            "our body:",
+            "this is the body",
+            "this is b",
+            "our body:",
+            "this is the nested body",
+            "this is aa is done",
+            "this is aa is done"
+        ]
+ 
+    def test_call_in_nested_2(self):
+        t = Template("""
+            <%def name="a()">
+                <%def name="d()">
+                    not this d
+                </%def>
+                this is a ${b()}
+                <%def name="b()">
+                    <%def name="d()">
+                        not this d either
+                    </%def>
+                    this is b
+                    <%call expr="c()">
+                        <%def name="d()">
+                            this is d
+                        </%def>
+                        this is the body in b's call
+                    </%call>
+                </%def>
+                <%def name="c()">
+                    this is c: ${caller.body()}
+                    the embedded "d" is: ${caller.d()}
+                </%def>
+            </%def>
+        ${a()}
+""")
+        assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call", 'the embedded "d" is:', 'this is d']
+
+class SelfCacheTest(TemplateTest):
+    """this test uses a now non-public API."""
+ 
+    def test_basic(self):
+        t = Template("""
+        <%!
+            cached = None
+        %>
+        <%def name="foo()">
+            <% 
+                global cached
+                if cached:
+                    return "cached: " + cached
+                __M_writer = context._push_writer()
+            %>
+            this is foo
+            <%
+                buf, __M_writer = context._pop_buffer_and_writer()
+                cached = buf.getvalue()
+                return cached
+            %>
+        </%def>
+ 
+        ${foo()}
+        ${foo()}
+""")
+        assert result_lines(t.render()) == [
+            "this is foo",
+            "cached:",
+            "this is foo"
+        ]
+ 
diff --git a/lib3/Mako-0.7.3/test/test_decorators.py b/lib3/Mako-0.7.3/test/test_decorators.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_decorators.py
@@ -0,0 +1,110 @@
+from mako.template import Template
+from mako import lookup
+import unittest
+from .util import flatten_result, result_lines
+
+class DecoratorTest(unittest.TestCase):
+    def test_toplevel(self):
+        template = Template("""
+            <%!
+                def bar(fn):
+                    def decorate(context, *args, **kw):
+                        return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR"
+                    return decorate
+            %>
+ 
+            <%def name="foo(y, x)" decorator="bar">
+                this is foo ${y} ${x}
+            </%def>
+ 
+            ${foo(1, x=5)}
+        """)
+
+        assert flatten_result(template.render()) == "BAR this is foo 1 5 BAR"
+
+    def test_toplevel_contextual(self):
+        template = Template("""
+            <%!
+                def bar(fn):
+                    def decorate(context):
+                        context.write("BAR")
+                        fn()
+                        context.write("BAR")
+                        return ''
+                    return decorate
+            %>
+
+            <%def name="foo()" decorator="bar">
+                this is foo
+            </%def>
+
+            ${foo()}
+        """)
+
+        assert flatten_result(template.render()) == "BAR this is foo BAR"
+
+        assert flatten_result(template.get_def('foo').render()) == "BAR this is foo BAR"
+
+
+    def test_nested(self):
+        template = Template("""
+            <%!
+                def bat(fn):
+                    def decorate(context):
+                        return "BAT" + runtime.capture(context, fn) + "BAT"
+                    return decorate
+            %>
+
+            <%def name="foo()">
+ 
+                <%def name="bar()" decorator="bat">
+                    this is bar
+                </%def>
+                ${bar()}
+            </%def>
+
+            ${foo()}
+        """)
+
+        assert flatten_result(template.render()) == "BAT this is bar BAT"
+ 
+    def test_toplevel_decorated_name(self):
+        template = Template("""
+            <%!
+                def bar(fn):
+                    def decorate(context, *args, **kw):
+                        return "function " + fn.__name__ + " " + runtime.capture(context, fn, *args, **kw)
+                    return decorate
+            %>
+
+            <%def name="foo(y, x)" decorator="bar">
+                this is foo ${y} ${x}
+            </%def>
+
+            ${foo(1, x=5)}
+        """)
+
+        assert flatten_result(template.render()) == "function foo this is foo 1 5"
+
+    def test_nested_decorated_name(self):
+        template = Template("""
+            <%!
+                def bat(fn):
+                    def decorate(context):
+                        return "function " + fn.__name__ + " " + runtime.capture(context, fn)
+                    return decorate
+            %>
+
+            <%def name="foo()">
+
+                <%def name="bar()" decorator="bat">
+                    this is bar
+                </%def>
+                ${bar()}
+            </%def>
+
+            ${foo()}
+        """)
+
+        assert flatten_result(template.render()) == "function bar this is bar"
+ 
diff --git a/lib3/Mako-0.7.3/test/test_def.py b/lib3/Mako-0.7.3/test/test_def.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_def.py
@@ -0,0 +1,678 @@
+from mako.template import Template
+from mako import lookup
+from test import TemplateTest
+from .util import flatten_result, result_lines
+from test import eq_, assert_raises
+
+class DefTest(TemplateTest):
+    def test_def_noargs(self):
+        template = Template("""
+
+        ${mycomp()}
+
+        <%def name="mycomp()">
+            hello mycomp ${variable}
+        </%def>
+
+        """)
+        eq_(
+            template.render(variable='hi').strip(),
+            """hello mycomp hi"""
+        )
+
+    def test_def_blankargs(self):
+        template = Template("""
+        <%def name="mycomp()">
+            hello mycomp ${variable}
+        </%def>
+
+        ${mycomp()}""")
+        eq_(
+            template.render(variable='hi').strip(),
+            "hello mycomp hi"
+        )
+
+    def test_def_args(self):
+        template = Template("""
+        <%def name="mycomp(a, b)">
+            hello mycomp ${variable}, ${a}, ${b}
+        </%def>
+
+        ${mycomp(5, 6)}""")
+        eq_(
+            template.render(variable='hi', a=5, b=6).strip(),
+            """hello mycomp hi, 5, 6"""
+        )
+
+    def test_inter_def(self):
+        """test defs calling each other"""
+        template = Template("""
+        ${b()}
+
+        <%def name="a()">\
+        im a
+        </%def>
+
+        <%def name="b()">
+        im b
+        and heres a:  ${a()}
+        </%def>
+
+        <%def name="c()">
+        im c
+        </%def>
+""")
+        # check that "a" is declared in "b", but not in "c"
+        assert "a" not in template.module.render_c.__code__.co_varnames
+        assert "a" in template.module.render_b.__code__.co_varnames
+
+        # then test output
+        eq_(
+            flatten_result(template.render()),
+            "im b and heres a: im a"
+        )
+
+    def test_toplevel(self):
+        """test calling a def from the top level"""
+
+        template = Template("""
+
+            this is the body
+
+            <%def name="a()">
+                this is a
+            </%def>
+
+            <%def name="b(x, y)">
+                this is b, ${x} ${y}
+            </%def>
+
+        """)
+
+        self._do_test(template.get_def("a"),
+                    "this is a",
+                    filters=flatten_result)
+        self._do_test(template.get_def("b"),
+                    "this is b, 10 15",
+                    template_args={'x': 10, 'y': 15},
+                    filters=flatten_result)
+        self._do_test(template.get_def("body"),
+                    "this is the body",
+                    filters=flatten_result)
+
+        # test that args outside of the dict can be used
+        self._do_test(template.get_def("a"), "this is a",
+                        filters=flatten_result,
+                        template_args={'q': 5, 'zq': 'test'})
+
+class ScopeTest(TemplateTest):
+    """test scoping rules.  The key is, enclosing
+    scope always takes precedence over contextual scope."""
+
+    def test_scope_one(self):
+        self._do_memory_test("""
+        <%def name="a()">
+            this is a, and y is ${y}
+        </%def>
+
+        ${a()}
+
+        <%
+            y = 7
+        %>
+
+        ${a()}
+
+""",
+            "this is a, and y is None this is a, and y is 7",
+            filters=flatten_result,
+            template_args={'y': None}
+        )
+
+    def test_scope_two(self):
+        t = Template("""
+        y is ${y}
+
+        <%
+            y = 7
+        %>
+
+        y is ${y}
+""")
+        try:
+            t.render(y=None)
+            assert False
+        except UnboundLocalError:
+            assert True
+
+    def test_scope_four(self):
+        """test that variables are pulled
+        from 'enclosing' scope before context."""
+        t = Template("""
+            <%
+                x = 5
+            %>
+            <%def name="a()">
+                this is a. x is ${x}.
+            </%def>
+
+            <%def name="b()">
+                <%
+                    x = 9
+                %>
+                this is b. x is ${x}.
+                calling a. ${a()}
+            </%def>
+
+            ${b()}
+""")
+        eq_(
+            flatten_result(t.render()),
+            "this is b. x is 9. calling a. this is a. x is 5."
+        )
+
+    def test_scope_five(self):
+        """test that variables are pulled from
+        'enclosing' scope before context."""
+        # same as test four, but adds a scope around it.
+        t = Template("""
+            <%def name="enclosing()">
+            <%
+                x = 5
+            %>
+            <%def name="a()">
+                this is a. x is ${x}.
+            </%def>
+
+            <%def name="b()">
+                <%
+                    x = 9
+                %>
+                this is b. x is ${x}.
+                calling a. ${a()}
+            </%def>
+
+            ${b()}
+            </%def>
+            ${enclosing()}
+""")
+        eq_(
+            flatten_result(t.render()),
+            "this is b. x is 9. calling a. this is a. x is 5."
+        )
+
+    def test_scope_six(self):
+        """test that the initial context counts
+        as 'enclosing' scope, for plain defs"""
+        t = Template("""
+
+        <%def name="a()">
+            a: x is ${x}
+        </%def>
+
+        <%def name="b()">
+            <%
+                x = 10
+            %>
+            b. x is ${x}.  ${a()}
+        </%def>
+
+        ${b()}
+    """)
+        eq_(
+            flatten_result(t.render(x=5)),
+            "b. x is 10. a: x is 5"
+        )
+
+    def test_scope_seven(self):
+        """test that the initial context counts
+        as 'enclosing' scope, for nested defs"""
+        t = Template("""
+        <%def name="enclosing()">
+            <%def name="a()">
+                a: x is ${x}
+            </%def>
+
+            <%def name="b()">
+                <%
+                    x = 10
+                %>
+                b. x is ${x}.  ${a()}
+            </%def>
+
+            ${b()}
+        </%def>
+        ${enclosing()}
+    """)
+        eq_(
+            flatten_result(t.render(x=5)),
+            "b. x is 10. a: x is 5"
+        )
+
+    def test_scope_eight(self):
+        """test that the initial context counts
+        as 'enclosing' scope, for nested defs"""
+        t = Template("""
+        <%def name="enclosing()">
+            <%def name="a()">
+                a: x is ${x}
+            </%def>
+
+            <%def name="b()">
+                <%
+                    x = 10
+                %>
+
+                b. x is ${x}.  ${a()}
+            </%def>
+
+            ${b()}
+        </%def>
+        ${enclosing()}
+    """)
+        eq_(
+            flatten_result(t.render(x=5)),
+            "b. x is 10. a: x is 5"
+        )
+
+    def test_scope_nine(self):
+        """test that 'enclosing scope' doesnt
+        get exported to other templates"""
+
+        l = lookup.TemplateLookup()
+        l.put_string('main', """
+        <%
+            x = 5
+        %>
+        this is main.  <%include file="secondary"/>
+""")
+
+        l.put_string('secondary', """
+        this is secondary.  x is ${x}
+""")
+
+        eq_(
+            flatten_result(l.get_template('main').render(x=2)),
+            "this is main. this is secondary. x is 2"
+        )
+
+    def test_scope_ten(self):
+        t = Template("""
+            <%def name="a()">
+                <%def name="b()">
+                    <%
+                        y = 19
+                    %>
+                    b/c: ${c()}
+                    b/y: ${y}
+                </%def>
+                <%def name="c()">
+                    c/y: ${y}
+                </%def>
+
+                <%
+                    # we assign to "y".  but the 'enclosing
+                    # scope' of "b" and "c" is from
+                    # the "y" on the outside
+                    y = 10
+                %>
+                a/y: ${y}
+                a/b: ${b()}
+            </%def>
+
+            <%
+                y = 7
+            %>
+            main/a: ${a()}
+            main/y: ${y}
+    """)
+        eq_(
+            flatten_result(t.render()),
+            "main/a: a/y: 10 a/b: b/c: c/y: 10 b/y: 19 main/y: 7"
+        )
+
+    def test_scope_eleven(self):
+        t = Template("""
+            x is ${x}
+            <%def name="a(x)">
+                this is a, ${b()}
+                <%def name="b()">
+                    this is b, x is ${x}
+                </%def>
+            </%def>
+
+            ${a(x=5)}
+""")
+        eq_(
+            result_lines(t.render(x=10)),
+        [
+            "x is 10",
+            "this is a,",
+            "this is b, x is 5"
+        ])
+
+    def test_unbound_scope(self):
+        t = Template("""
+            <%
+                y = 10
+            %>
+            <%def name="a()">
+                y is: ${y}
+                <%
+                    # should raise error ?
+                    y = 15
+                %>
+                y is ${y}
+            </%def>
+            ${a()}
+""")
+        assert_raises(
+            UnboundLocalError,
+            t.render
+            )
+
+    def test_unbound_scope_two(self):
+        t = Template("""
+            <%def name="enclosing()">
+            <%
+                y = 10
+            %>
+            <%def name="a()">
+                y is: ${y}
+                <%
+                    # should raise error ?
+                    y = 15
+                %>
+                y is ${y}
+            </%def>
+            ${a()}
+            </%def>
+            ${enclosing()}
+""")
+        try:
+            print(t.render())
+            assert False
+        except UnboundLocalError:
+            assert True
+
+    def test_canget_kwargs(self):
+        """test that arguments passed to the body()
+        function are accessible by top-level defs"""
+        l = lookup.TemplateLookup()
+        l.put_string("base", """
+
+        ${next.body(x=12)}
+
+        """)
+
+        l.put_string("main", """
+            <%inherit file="base"/>
+            <%page args="x"/>
+            this is main.  x is ${x}
+
+            ${a()}
+
+            <%def name="a(**args)">
+                this is a, x is ${x}
+            </%def>
+        """)
+
+        # test via inheritance
+        eq_(
+            result_lines(l.get_template("main").render()),
+            [
+            "this is main. x is 12",
+            "this is a, x is 12"
+        ])
+
+        l.put_string("another", """
+            <%namespace name="ns" file="main"/>
+
+            ${ns.body(x=15)}
+        """)
+        # test via namespace
+        eq_(
+            result_lines(l.get_template("another").render()),
+        [
+            "this is main. x is 15",
+            "this is a, x is 15"
+        ])
+
+    def test_inline_expression_from_arg_one(self):
+        """test that cache_key=${foo} gets its value from
+        the 'foo' argument in the <%def> tag,
+        and strict_undefined doesn't complain.
+
+        this is #191.
+
+        """
+        t = Template("""
+        <%def name="layout(foo)" cached="True" cache_key="${foo}">
+        foo: ${foo}
+        </%def>
+
+        ${layout(3)}
+        """, strict_undefined=True,
+            cache_impl="plain")
+
+        eq_(
+            result_lines(t.render()),
+            ["foo: 3"]
+        )
+
+    def test_interpret_expression_from_arg_two(self):
+        """test that cache_key=${foo} gets its value from
+        the 'foo' argument regardless of it being passed
+        from the context.
+
+        This is here testing that there's no change
+        to existing behavior before and after #191.
+
+        """
+        t = Template("""
+        <%def name="layout(foo)" cached="True" cache_key="${foo}">
+        foo: ${value}
+        </%def>
+
+        ${layout(3)}
+        """, cache_impl="plain")
+
+        eq_(
+            result_lines(t.render(foo='foo', value=1)),
+            ["foo: 1"]
+        )
+        eq_(
+            result_lines(t.render(foo='bar', value=2)),
+            ["foo: 1"]
+        )
+
+class NestedDefTest(TemplateTest):
+    def test_nested_def(self):
+        t = Template("""
+
+        ${hi()}
+
+        <%def name="hi()">
+            hey, im hi.
+            and heres ${foo()}, ${bar()}
+
+            <%def name="foo()">
+                this is foo
+            </%def>
+
+            <%def name="bar()">
+                this is bar
+            </%def>
+        </%def>
+""")
+        eq_(
+            flatten_result(t.render()),
+            "hey, im hi. and heres this is foo , this is bar"
+        )
+
+    def test_nested_2(self):
+        t = Template("""
+            x is ${x}
+            <%def name="a()">
+                this is a, x is ${x}
+                ${b()}
+                <%def name="b()">
+                    this is b: ${x}
+                </%def>
+            </%def>
+            ${a()}
+""")
+
+        eq_(
+            flatten_result(t.render(x=10)),
+            "x is 10 this is a, x is 10 this is b: 10"
+        )
+
+    def test_nested_with_args(self):
+        t = Template("""
+        ${a()}
+        <%def name="a()">
+            <%def name="b(x, y=2)">
+                b x is ${x} y is ${y}
+            </%def>
+            a ${b(5)}
+        </%def>
+""")
+        eq_(
+            flatten_result(t.render()),
+            "a b x is 5 y is 2"
+        )
+
+    def test_nested_def_2(self):
+        template = Template("""
+        ${a()}
+        <%def name="a()">
+            <%def name="b()">
+                <%def name="c()">
+                    comp c
+                </%def>
+                ${c()}
+            </%def>
+            ${b()}
+        </%def>
+""")
+        eq_(
+            flatten_result(template.render()),
+            "comp c"
+        )
+
+    def test_nested_nested_def(self):
+        t = Template("""
+
+        ${a()}
+        <%def name="a()">
+            a
+            <%def name="b1()">
+                a_b1
+            </%def>
+            <%def name="b2()">
+                a_b2 ${c1()}
+                <%def name="c1()">
+                    a_b2_c1
+                </%def>
+            </%def>
+            <%def name="b3()">
+                a_b3 ${c1()}
+                <%def name="c1()">
+                    a_b3_c1 heres x: ${x}
+                    <%
+                        y = 7
+                    %>
+                    y is ${y}
+                </%def>
+                <%def name="c2()">
+                    a_b3_c2
+                    y is ${y}
+                    c1 is ${c1()}
+                </%def>
+                ${c2()}
+            </%def>
+
+            ${b1()} ${b2()}  ${b3()}
+        </%def>
+""")
+        eq_(
+            flatten_result(t.render(x=5, y=None)),
+            "a a_b1 a_b2 a_b2_c1 a_b3 a_b3_c1 "
+            "heres x: 5 y is 7 a_b3_c2 y is "
+            "None c1 is a_b3_c1 heres x: 5 y is 7"
+        )
+
+    def test_nested_nested_def_2(self):
+        t = Template("""
+        <%def name="a()">
+            this is a ${b()}
+            <%def name="b()">
+                this is b
+                ${c()}
+            </%def>
+
+            <%def name="c()">
+                this is c
+            </%def>
+        </%def>
+        ${a()}
+""")
+        eq_(
+            flatten_result(t.render()),
+            "this is a this is b this is c"
+        )
+
+    def test_outer_scope(self):
+        t = Template("""
+        <%def name="a()">
+            a: x is ${x}
+        </%def>
+
+        <%def name="b()">
+            <%def name="c()">
+            <%
+                x = 10
+            %>
+            c. x is ${x}.  ${a()}
+            </%def>
+
+            b. ${c()}
+        </%def>
+
+        ${b()}
+
+        x is ${x}
+""")
+        eq_(
+            flatten_result(t.render(x=5)),
+            "b. c. x is 10. a: x is 5 x is 5"
+        )
+
+class ExceptionTest(TemplateTest):
+    def test_raise(self):
+        template = Template("""
+            <%
+                raise Exception("this is a test")
+            %>
+    """, format_exceptions=False)
+        assert_raises(
+            Exception,
+            template.render
+            )
+
+    def test_handler(self):
+        def handle(context, error):
+            context.write("error message is " + str(error))
+            return True
+
+        template = Template("""
+            <%
+                raise Exception("this is a test")
+            %>
+    """, error_handler=handle)
+        eq_(
+            template.render().strip(),
+            "error message is this is a test"
+        )
+
diff --git a/lib3/Mako-0.7.3/test/test_exceptions.py b/lib3/Mako-0.7.3/test/test_exceptions.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_exceptions.py
@@ -0,0 +1,299 @@
+# -*- coding: utf-8 -*-
+import sys
+import unittest
+
+from mako import exceptions, util
+from mako.template import Template
+from mako.lookup import TemplateLookup
+from .util import result_lines
+from test import template_base, module_base, TemplateTest
+from test import requires_pygments_14, requires_no_pygments, \
+    requires_python_25_or_greater
+
+
+class ExceptionsTest(TemplateTest):
+    def test_html_error_template(self):
+        """test the html_error_template"""
+        code = """
+% i = 0
+"""
+        try:
+            template = Template(code)
+            template.render_unicode()
+            assert False
+        except exceptions.CompileException as ce:
+            html_error = exceptions.html_error_template().render_unicode()
+            assert ("CompileException: Fragment 'i = 0' is not "
+                    "a partial control statement at line: 2 char: 1") in html_error
+            assert '<style>' in html_error
+            html_error_stripped = html_error.strip()
+            assert html_error_stripped.startswith('<html>')
+            assert html_error_stripped.endswith('</html>')
+
+            not_full = exceptions.html_error_template().\
+                                    render_unicode(full=False)
+            assert '<html>' not in not_full
+            assert '<style>' in not_full
+
+            no_css = exceptions.html_error_template().\
+                                    render_unicode(css=False)
+            assert '<style>' not in no_css
+        else:
+            assert False, ("This function should trigger a CompileException, "
+                           "but didn't")
+
+    def test_text_error_template(self):
+        code = """
+% i = 0
+"""
+        try:
+            template = Template(code)
+            template.render_unicode()
+            assert False
+        except exceptions.CompileException as ce:
+            text_error = exceptions.text_error_template().render_unicode()
+            assert 'Traceback (most recent call last):' in text_error
+            assert ("CompileException: Fragment 'i = 0' is not a partial "
+                    "control statement") in text_error
+
+    @requires_pygments_14
+    def test_utf8_html_error_template_pygments(self):
+        """test the html_error_template with a Template containing utf8
+        chars"""
+
+        if util.py3k:
+            code = """# -*- coding: utf-8 -*-
+% if 2 == 2: /an error
+${'привет'}
+% endif
+"""
+        else:
+            code = """# -*- coding: utf-8 -*-
+% if 2 == 2: /an error
+${u'привет'}
+% endif
+"""
+        try:
+            template = Template(code)
+            template.render_unicode()
+        except exceptions.CompileException as ce:
+            html_error = exceptions.html_error_template().render()
+            if util.py3k:
+                assert ("CompileException: Fragment 'if 2 == 2: /an "
+                    "error' is not a partial control statement "
+                    "at line: 2 char: 1").encode(sys.getdefaultencoding(), 'htmlentityreplace') in \
+                    html_error
+            else:
+                assert ("CompileException: Fragment 'if 2 == 2: /an "
+                        "error' is not a partial control statement "
+                        "at line: 2 char: 1") in \
+                        html_error
+
+            if util.py3k:
+                assert "".encode(sys.getdefaultencoding(),
+                                        'htmlentityreplace') in html_error
+            else:
+                assert '<pre>3</pre></div></td><td class="code">'\
+                        '<div class="syntax-highlighted"><pre><span '\
+                        'class="cp">${</span><span class="s">u''\
+                        '&#x43F;&#x440;&#x438;&#x432;&#x435;&#x442;'\
+                        ''</span><span class="cp">}</span>'.encode(
+                                sys.getdefaultencoding(),
+                                'htmlentityreplace') in html_error
+        else:
+            assert False, ("This function should trigger a CompileException, "
+                           "but didn't")
+
+    @requires_no_pygments
+    def test_utf8_html_error_template_no_pygments(self):
+        """test the html_error_template with a Template containing utf8
+        chars"""
+
+        if util.py3k:
+            code = """# -*- coding: utf-8 -*-
+% if 2 == 2: /an error
+${'привет'}
+% endif
+"""
+        else:
+            code = """# -*- coding: utf-8 -*-
+% if 2 == 2: /an error
+${u'привет'}
+% endif
+"""
+        try:
+            template = Template(code)
+            template.render_unicode()
+        except exceptions.CompileException as ce:
+            html_error = exceptions.html_error_template().render()
+            if util.py3k:
+                assert ("CompileException: Fragment 'if 2 == 2: /an "
+                    "error' is not a partial control statement "
+                    "at line: 2 char: 1").encode(sys.getdefaultencoding(), 'htmlentityreplace') in \
+                    html_error
+            else:
+                assert ("CompileException: Fragment 'if 2 == 2: /an "
+                        "error' is not a partial control statement "
+                        "at line: 2 char: 1") in \
+                        html_error
+
+            if util.py3k:
+                assert "${'привет'}".encode(sys.getdefaultencoding(),
+                                        'htmlentityreplace') in html_error
+            else:
+                assert "${u'привет'}".encode(sys.getdefaultencoding(),
+                                        'htmlentityreplace') in html_error
+        else:
+            assert False, ("This function should trigger a CompileException, "
+                           "but didn't")
+
+    def test_format_closures(self):
+        try:
+            exec("def foo():"\
+                 "    raise RuntimeError('test')", locals())
+            foo()
+        except:
+            html_error = exceptions.html_error_template().render()
+            assert "RuntimeError: test" in str(html_error)
+
+    @requires_python_25_or_greater
+    def test_py_utf8_html_error_template(self):
+        try:
+            foo = '日本'
+            raise RuntimeError('test')
+        except:
+            html_error = exceptions.html_error_template().render()
+            if util.py3k:
+                assert 'RuntimeError: test' in html_error.decode('utf-8')
+                assert "foo = '日本'" in html_error.decode('utf-8')
+            else:
+                assert 'RuntimeError: test' in html_error
+                assert "foo = u'&#x65E5;&#x672C;'" in html_error
+
+    def test_py_unicode_error_html_error_template(self):
+        try:
+            raise RuntimeError('日本')
+        except:
+            html_error = exceptions.html_error_template().render()
+            assert "RuntimeError: 日本".encode('ascii', 'ignore') in html_error
+
+    @requires_pygments_14
+    def test_format_exceptions_pygments(self):
+        l = TemplateLookup(format_exceptions=True)
+
+        l.put_string("foo.html", """
+<%inherit file="base.html"/>
+${foobar}
+        """)
+
+        l.put_string("base.html", """
+        ${self.body()}
+        """)
+
+        assert '<div class="sourceline"><table class="syntax-highlightedtable">'\
+                '<tr><td class="linenos"><div class="linenodiv"><pre>3</pre>'\
+                '</div></td><td class="code"><div class="syntax-highlighted">'\
+                '<pre><span class="err">$</span><span class="p">{</span>'\
+                '<span class="n">foobar</span><span class="p">}</span>' in \
+            result_lines(l.get_template("foo.html").render_unicode())
+
+    @requires_no_pygments
+    def test_format_exceptions_no_pygments(self):
+        l = TemplateLookup(format_exceptions=True)
+
+        l.put_string("foo.html", """
+<%inherit file="base.html"/>
+${foobar}
+        """)
+
+        l.put_string("base.html", """
+        ${self.body()}
+        """)
+
+        assert '<div class="sourceline">${foobar}</div>' in \
+            result_lines(l.get_template("foo.html").render_unicode())
+
+    @requires_pygments_14
+    def test_utf8_format_exceptions_pygments(self):
+        """test that htmlentityreplace formatting is applied to
+           exceptions reported with format_exceptions=True"""
+
+        l = TemplateLookup(format_exceptions=True)
+        if util.py3k:
+            l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${'привет' + foobar}""")
+        else:
+            l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${u'привет' + foobar}""")
+
+        if util.py3k:
+            assert '<table class="error syntax-highlightedtable"><tr><td '\
+                    'class="linenos"><div class="linenodiv"><pre>2</pre>'\
+                    '</div></td><td class="code"><div class="error '\
+                    'syntax-highlighted"><pre><span class="cp">${</span>'\
+                    '<span class="s">'привет'</span> <span class="o">+</span> '\
+                    '<span class="n">foobar</span><span class="cp">}</span>'\
+                    '<span class="x"></span>' in \
+                result_lines(l.get_template("foo.html").render().decode('utf-8'))
+        else:
+            assert '<table class="error syntax-highlightedtable"><tr><td '\
+                    'class="linenos"><div class="linenodiv"><pre>2</pre>'\
+                    '</div></td><td class="code"><div class="error '\
+                    'syntax-highlighted"><pre><span class="cp">${</span>'\
+                    '<span class="s">u'&#x43F;&#x440;&#x438;&#x432;'\
+                    '&#x435;&#x442;'</span> <span class="o">+</span> '\
+                    '<span class="n">foobar</span><span class="cp">}</span>'\
+                    '<span class="x"></span>' in \
+                result_lines(l.get_template("foo.html").render().decode('utf-8'))
+
+    @requires_no_pygments
+    def test_utf8_format_exceptions_no_pygments(self):
+        """test that htmlentityreplace formatting is applied to
+           exceptions reported with format_exceptions=True"""
+
+        l = TemplateLookup(format_exceptions=True)
+        if util.py3k:
+            l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${'привет' + foobar}""")
+        else:
+            l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${u'привет' + foobar}""")
+
+        if util.py3k:
+            assert '<div class="sourceline">${'привет' + foobar}</div>'\
+                in result_lines(l.get_template("foo.html").render().decode('utf-8'))
+        else:
+            assert '${u'&#x43F;&#x440;&#x438;&#x432;&#x435;'\
+                   '&#x442;' + foobar}' in \
+                result_lines(l.get_template("foo.html").render().decode('utf-8'))
+
+
+    @requires_python_25_or_greater
+    def test_custom_tback(self):
+        try:
+            raise RuntimeError("error 1")
+            foo('bar')
+        except:
+            t, v, tback = sys.exc_info()
+
+        try:
+            raise RuntimeError("error 2")
+        except:
+            html_error = exceptions.html_error_template().\
+                        render_unicode(error=v, traceback=tback)
+
+        # obfuscate the text so that this text
+        # isn't in the 'wrong' exception
+        assert "".join(reversed(");93#&rab;93#&(oof")) in html_error
+
+    def test_tback_no_trace(self):
+        try:
+            t = self._file_template("runtimeerr.html")
+            t.render()
+        except:
+            t, v, tback = sys.exc_info()
+
+        if not util.py3k:
+            # blow away tracebaack info
+            sys.exc_clear()
+
+        # and don't even send what we have.
+        html_error = exceptions.html_error_template().\
+                    render_unicode(error=v, traceback=None)
+        assert "local variable 'y' referenced before assignment" in html_error
diff --git a/lib3/Mako-0.7.3/test/test_filters.py b/lib3/Mako-0.7.3/test/test_filters.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_filters.py
@@ -0,0 +1,335 @@
+# -*- coding: utf-8 -*-
+
+from mako.template import Template
+import unittest
+from test import TemplateTest, eq_, requires_python_2
+from .util import result_lines, flatten_result
+
+class FilterTest(TemplateTest):
+    def test_basic(self):
+        t = Template("""
+        ${x | myfilter}
+""")
+        assert flatten_result(t.render(x="this is x", myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t)) == "MYFILTER->this is x<-MYFILTER"
+
+    def test_expr(self):
+        """test filters that are themselves expressions"""
+        t = Template("""
+        ${x | myfilter(y)}
+""")
+        def myfilter(y):
+            return lambda x: "MYFILTER->%s<-%s" % (x, y)
+        assert flatten_result(t.render(x="this is x", myfilter=myfilter, y="this is y")) == "MYFILTER->this is x<-this is y"
+
+    def test_convert_str(self):
+        """test that string conversion happens in expressions before sending to filters"""
+        t = Template("""
+            ${x | trim}
+        """)
+        assert flatten_result(t.render(x=5)) == "5"
+
+    def test_quoting(self):
+        t = Template("""
+            foo ${bar | h}
+        """)
+
+        eq_(
+            flatten_result(t.render(bar="<'some bar'>")),
+            "foo <'some bar'>"
+        )
+
+    @requires_python_2
+    def test_quoting_non_unicode(self):
+        t = Template("""
+            foo ${bar | h}
+        """, disable_unicode=True,
+        output_encoding=None)
+
+        eq_(
+            flatten_result(t.render(bar="<'привет'>")),
+            "foo <'привет'>"
+        )
+
+
+    def test_def(self):
+        t = Template("""
+            <%def name="foo()" filter="myfilter">
+                this is foo
+            </%def>
+            ${foo()}
+""")
+
+        eq_(
+            flatten_result(t.render(x="this is x",
+                        myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t)),
+            "MYFILTER-> this is foo <-MYFILTER"
+        )
+
+    def test_import(self):
+        t = Template("""
+        <%!
+            from mako import filters
+        %>\
+        trim this string: ${"  some string to trim   " | filters.trim} continue\
+        """)
+
+        assert t.render().strip()=="trim this string: some string to trim continue"
+
+    def test_import_2(self):
+        t = Template("""
+        trim this string: ${"  some string to trim   " | filters.trim} continue\
+        """, imports=["from mako import filters"])
+        #print t.code
+        assert t.render().strip()=="trim this string: some string to trim continue"
+
+    def test_encode_filter(self):
+        t = Template("""# coding: utf-8
+            some stuff.... ${x}
+        """, default_filters=['decode.utf8'])
+        #print t.code
+        assert t.render_unicode(x="voix m’a réveillé").strip() == "some stuff.... voix m’a réveillé"
+
+    def test_custom_default(self):
+        t = Template("""
+        <%!
+            def myfilter(x):
+                return "->" + x + "<-"
+        %>
+
+            hi ${'there'}
+        """, default_filters=['myfilter'])
+        assert t.render().strip()=="hi ->there<-"
+
+    def test_global(self):
+        t = Template("""
+            <%page expression_filter="h"/>
+            ${"<tag>this is html</tag>"}
+        """)
+        assert t.render().strip()  == "<tag>this is html</tag>"
+
+    def test_block_via_context(self):
+        t = Template("""
+            <%block name="foo" filter="myfilter">
+                some text
+            </%block>
+        """)
+        def myfilter(text):
+            return "MYTEXT" + text
+        eq_(
+            result_lines(t.render(myfilter=myfilter)),
+            ["MYTEXT", "some text"]
+        )
+
+    def test_def_via_context(self):
+        t = Template("""
+            <%def name="foo()" filter="myfilter">
+                some text
+            </%def>
+            ${foo()}
+        """)
+        def myfilter(text):
+            return "MYTEXT" + text
+        eq_(
+            result_lines(t.render(myfilter=myfilter)),
+            ["MYTEXT", "some text"]
+        )
+
+    def test_text_via_context(self):
+        t = Template("""
+            <%text filter="myfilter">
+                some text
+            </%text>
+        """)
+        def myfilter(text):
+            return "MYTEXT" + text
+        eq_(
+            result_lines(t.render(myfilter=myfilter)),
+            ["MYTEXT", "some text"]
+        )
+
+
+    def test_nflag(self):
+        t = Template("""
+            ${"<tag>this is html</tag>" | n}
+        """, default_filters=['h', 'unicode'])
+        assert t.render().strip()  == "<tag>this is html</tag>"
+
+        t = Template("""
+            <%page expression_filter="h"/>
+            ${"<tag>this is html</tag>" | n}
+        """)
+        assert t.render().strip()  == "<tag>this is html</tag>"
+
+        t = Template("""
+            <%page expression_filter="h"/>
+            ${"<tag>this is html</tag>" | n, h}
+        """)
+        assert t.render().strip()  == "<tag>this is html</tag>"
+
+    def test_non_expression(self):
+        t = Template("""
+        <%!
+            def a(text):
+                return "this is a"
+            def b(text):
+                return "this is b"
+        %>
+
+        ${foo()}
+        <%def name="foo()" buffered="True">
+            this is text
+        </%def>
+        """, buffer_filters=['a'])
+        assert t.render().strip() == "this is a"
+
+        t = Template("""
+        <%!
+            def a(text):
+                return "this is a"
+            def b(text):
+                return "this is b"
+        %>
+
+        ${'hi'}
+        ${foo()}
+        <%def name="foo()" buffered="True">
+            this is text
+        </%def>
+        """, buffer_filters=['a'], default_filters=['b'])
+        assert flatten_result(t.render()) == "this is b this is b"
+
+        t = Template("""
+        <%!
+            class Foo(object):
+                foo = True
+                def __str__(self):
+                    return "this is a"
+            def a(text):
+                return Foo()
+            def b(text):
+                if hasattr(text, 'foo'):
+                    return str(text)
+                else:
+                    return "this is b"
+        %>
+
+        ${'hi'}
+        ${foo()}
+        <%def name="foo()" buffered="True">
+            this is text
+        </%def>
+        """, buffer_filters=['a'], default_filters=['b'])
+        assert flatten_result(t.render()) == "this is b this is a"
+
+        t = Template("""
+        <%!
+            def a(text):
+                return "this is a"
+            def b(text):
+                return "this is b"
+        %>
+
+        ${foo()}
+        ${bar()}
+        <%def name="foo()" filter="b">
+            this is text
+        </%def>
+        <%def name="bar()" filter="b" buffered="True">
+            this is text
+        </%def>
+        """, buffer_filters=['a'])
+        assert flatten_result(t.render()) == "this is b this is a"
+
+
+    def test_builtins(self):
+        t = Template("""
+            ${"this is <text>" | h}
+""")
+        assert flatten_result(t.render()) == "this is <text>"
+
+        t = Template("""
+            http://foo.com/arg1=${"hi! this is a string." | u}
+""")
+        assert flatten_result(t.render()) == "http://foo.com/arg1=hi%21+this+is+a+string."
+
+class BufferTest(unittest.TestCase):
+    def test_buffered_def(self):
+        t = Template("""
+            <%def name="foo()" buffered="True">
+                this is foo
+            </%def>
+            ${"hi->" + foo() + "<-hi"}
+""")
+        assert flatten_result(t.render()) == "hi-> this is foo <-hi"
+
+    def test_unbuffered_def(self):
+        t = Template("""
+            <%def name="foo()" buffered="False">
+                this is foo
+            </%def>
+            ${"hi->" + foo() + "<-hi"}
+""")
+        assert flatten_result(t.render()) == "this is foo hi-><-hi"
+
+    def test_capture(self):
+        t = Template("""
+            <%def name="foo()" buffered="False">
+                this is foo
+            </%def>
+            ${"hi->" + capture(foo) + "<-hi"}
+""")
+        assert flatten_result(t.render()) == "hi-> this is foo <-hi"
+
+    def test_capture_exception(self):
+        template = Template("""
+            <%def name="a()">
+                this is a
+                <%
+                    raise TypeError("hi")
+                %>
+            </%def>
+            <%
+                c = capture(a)
+            %>
+            a->${c}<-a
+        """)
+        try:
+            template.render()
+            assert False
+        except TypeError:
+            assert True
+
+    def test_buffered_exception(self):
+        template = Template("""
+            <%def name="a()" buffered="True">
+                <%
+                    raise TypeError("hi")
+                %>
+            </%def>
+
+            ${a()}
+
+""")
+        try:
+            print(template.render())
+            assert False
+        except TypeError:
+            assert True
+
+    def test_capture_ccall(self):
+        t = Template("""
+            <%def name="foo()">
+                <%
+                    x = capture(caller.body)
+                %>
+                this is foo.  body: ${x}
+            </%def>
+
+            <%call expr="foo()">
+                ccall body
+            </%call>
+""")
+
+        #print t.render()
+        assert flatten_result(t.render()) == "this is foo. body: ccall body"
+
diff --git a/lib3/Mako-0.7.3/test/test_inheritance.py b/lib3/Mako-0.7.3/test/test_inheritance.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_inheritance.py
@@ -0,0 +1,350 @@
+from mako.template import Template
+from mako import lookup, util
+import unittest
+from .util import flatten_result, result_lines
+
+class InheritanceTest(unittest.TestCase):
+    def test_basic(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main', """
+<%inherit file="base"/>
+
+<%def name="header()">
+    main header.
+</%def>
+
+this is the content.
+""")
+
+        collection.put_string('base', """
+This is base.
+
+header: ${self.header()}
+
+body: ${self.body()}
+
+footer: ${self.footer()}
+
+<%def name="footer()">
+    this is the footer. header again ${next.header()}
+</%def>
+""")
+
+        assert result_lines(collection.get_template('main').render()) == [
+            'This is base.',
+             'header:',
+             'main header.',
+             'body:',
+             'this is the content.',
+             'footer:',
+             'this is the footer. header again',
+             'main header.'
+        ]
+
+    def test_multilevel_nesting(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main', """
+<%inherit file="layout"/>
+<%def name="d()">main_d</%def>
+main_body ${parent.d()}
+full stack from the top:
+    ${self.name} ${parent.name} ${parent.context['parent'].name} ${parent.context['parent'].context['parent'].name}
+""")
+ 
+        collection.put_string('layout', """
+<%inherit file="general"/>
+<%def name="d()">layout_d</%def>
+layout_body
+parent name: ${parent.name}
+${parent.d()}
+${parent.context['parent'].d()}
+${next.body()}
+""")
+
+        collection.put_string('general', """
+<%inherit file="base"/>
+<%def name="d()">general_d</%def>
+general_body
+${next.d()}
+${next.context['next'].d()}
+${next.body()}
+""")
+        collection.put_string('base', """
+base_body
+full stack from the base:
+    ${self.name} ${self.context['parent'].name} ${self.context['parent'].context['parent'].name} ${self.context['parent'].context['parent'].context['parent'].name}
+${next.body()}
+<%def name="d()">base_d</%def>
+""")
+
+        assert result_lines(collection.get_template('main').render()) == [
+            'base_body',
+             'full stack from the base:',
+             'self:main self:layout self:general self:base',
+             'general_body',
+             'layout_d',
+             'main_d',
+             'layout_body',
+             'parent name: self:general',
+             'general_d',
+             'base_d',
+             'main_body layout_d',
+             'full stack from the top:',
+             'self:main self:layout self:general self:base'
+        ]
+ 
+    def test_includes(self):
+        """test that an included template also has its full hierarchy invoked."""
+        collection = lookup.TemplateLookup()
+ 
+        collection.put_string("base", """
+        <%def name="a()">base_a</%def>
+        This is the base.
+        ${next.body()}
+        End base.
+""")
+
+        collection.put_string("index","""
+        <%inherit file="base"/>
+        this is index.
+        a is: ${self.a()}
+        <%include file="secondary"/>
+""")
+
+        collection.put_string("secondary","""
+        <%inherit file="base"/>
+        this is secondary.
+        a is: ${self.a()}
+""")
+
+        assert result_lines(collection.get_template("index").render()) == [
+            'This is the base.', 
+            'this is index.',
+             'a is: base_a',
+             'This is the base.',
+             'this is secondary.',
+             'a is: base_a',
+             'End base.',
+             'End base.'
+            ]
+
+    def test_namespaces(self):
+        """test that templates used via <%namespace> have access to an inheriting 'self', and that
+        the full 'self' is also exported."""
+        collection = lookup.TemplateLookup()
+ 
+        collection.put_string("base", """
+        <%def name="a()">base_a</%def>
+        <%def name="b()">base_b</%def>
+        This is the base.
+        ${next.body()}
+""")
+
+        collection.put_string("layout", """
+        <%inherit file="base"/>
+        <%def name="a()">layout_a</%def>
+        This is the layout..
+        ${next.body()}
+""")
+
+        collection.put_string("index","""
+        <%inherit file="base"/>
+        <%namespace name="sc" file="secondary"/>
+        this is index.
+        a is: ${self.a()}
+        sc.a is: ${sc.a()}
+        sc.b is: ${sc.b()}
+        sc.c is: ${sc.c()}
+        sc.body is: ${sc.body()}
+""")
+
+        collection.put_string("secondary","""
+        <%inherit file="layout"/>
+        <%def name="c()">secondary_c.  a is ${self.a()} b is ${self.b()} d is ${self.d()}</%def>
+        <%def name="d()">secondary_d.</%def>
+        this is secondary.
+        a is: ${self.a()}
+        c is: ${self.c()}
+""")
+
+        assert result_lines(collection.get_template('index').render()) ==  ['This is the base.',
+         'this is index.',
+         'a is: base_a',
+         'sc.a is: layout_a',
+         'sc.b is: base_b',
+         'sc.c is: secondary_c. a is layout_a b is base_b d is secondary_d.',
+         'sc.body is:',
+         'this is secondary.',
+         'a is: layout_a',
+         'c is: secondary_c. a is layout_a b is base_b d is secondary_d.'
+         ]
+
+    def test_pageargs(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+
+            <%
+            sorted_ = pageargs.items()
+            sorted_ = sorted(sorted_)
+            %>
+            pageargs: (type: ${type(pageargs)}) ${sorted_}
+            <%def name="foo()">
+                ${next.body(**context.kwargs)}
+            </%def>
+ 
+            ${foo()}
+        """)
+        collection.put_string("index", """
+            <%inherit file="base"/>
+            <%page args="x, y, z=7"/>
+            print ${x}, ${y}, ${z}
+        """)
+ 
+        if util.py3k:
+            assert result_lines(collection.get_template('index').render_unicode(x=5,y=10)) == [
+                "this is the base.",
+                "pageargs: (type: <class 'dict'>) [('x', 5), ('y', 10)]",
+                "print 5, 10, 7"
+            ]
+        else:
+            assert result_lines(collection.get_template('index').render_unicode(x=5,y=10)) == [
+                "this is the base.",
+                "pageargs: (type: <type 'dict'>) [('x', 5), ('y', 10)]",
+                "print 5, 10, 7"
+            ]
+ 
+    def test_pageargs_2(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+ 
+            ${next.body(**context.kwargs)}
+ 
+            <%def name="foo(**kwargs)">
+                ${next.body(**kwargs)}
+            </%def>
+
+            <%def name="bar(**otherargs)">
+                ${next.body(z=16, **context.kwargs)}
+            </%def>
+
+            ${foo(x=12, y=15, z=8)}
+            ${bar(x=19, y=17)}
+        """)
+        collection.put_string("index", """
+            <%inherit file="base"/>
+            <%page args="x, y, z=7"/>
+            pageargs: ${x}, ${y}, ${z}
+        """)
+        assert result_lines(collection.get_template('index').render(x=5,y=10)) == [
+            "this is the base.",
+            "pageargs: 5, 10, 7",
+            "pageargs: 12, 15, 8",
+            "pageargs: 5, 10, 16"
+        ]
+ 
+    def test_pageargs_err(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+            ${next.body()}
+        """)
+        collection.put_string("index", """
+            <%inherit file="base"/>
+            <%page args="x, y, z=7"/>
+            print ${x}, ${y}, ${z}
+        """)
+        try:
+            print(collection.get_template('index').render(x=5,y=10))
+            assert False
+        except TypeError:
+            assert True
+ 
+    def test_toplevel(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+            ${next.body()}
+        """)
+        collection.put_string("index", """
+            <%inherit file="base"/>
+            this is the body
+        """)
+        assert result_lines(collection.get_template('index').render()) == [
+            "this is the base.",
+            "this is the body"
+        ]
+        assert result_lines(collection.get_template('index').get_def("body").render()) == [
+            "this is the body"
+        ]
+
+    def test_dynamic(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+            ${next.body()}
+        """)
+        collection.put_string("index", """
+            <%!
+                def dyn(context):
+                    if context.get('base', None) is not None:
+                        return 'base'
+                    else:
+                        return None
+            %>
+            <%inherit file="${dyn(context)}"/>
+            this is index.
+        """)
+        assert result_lines(collection.get_template('index').render()) == [
+            'this is index.'
+        ]
+        assert result_lines(collection.get_template('index').render(base=True)) == [
+            'this is the base.',
+            'this is index.'
+        ]
+ 
+    def test_in_call(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("/layout.html","""
+        Super layout!
+        <%call expr="self.grid()">
+            ${next.body()}
+        </%call>
+        Oh yea!
+
+        <%def name="grid()">
+            Parent grid
+                ${caller.body()}
+            End Parent
+        </%def>
+        """)
+
+
+        collection.put_string("/subdir/layout.html", """
+        ${next.body()}
+        <%def name="grid()">
+           Subdir grid
+               ${caller.body()}
+           End subdir
+        </%def>
+        <%inherit file="/layout.html"/>
+        """)
+ 
+        collection.put_string("/subdir/renderedtemplate.html","""
+        Holy smokes!
+        <%inherit file="/subdir/layout.html"/>
+        """)
+
+        #print collection.get_template("/layout.html").code
+        #print collection.get_template("/subdir/renderedtemplate.html").render()
+        assert result_lines(collection.get_template("/subdir/renderedtemplate.html").render()) == [
+            "Super layout!",
+            "Subdir grid",
+            "Holy smokes!",
+            "End subdir",
+            "Oh yea!"
+        ]
+
diff --git a/lib3/Mako-0.7.3/test/test_lexer.py b/lib3/Mako-0.7.3/test/test_lexer.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_lexer.py
@@ -0,0 +1,871 @@
+import unittest
+
+from mako.lexer import Lexer
+from mako import exceptions, util
+from .util import flatten_result, result_lines
+from mako.template import Template
+import re
+from test import TemplateTest, template_base, skip_if, eq_, assert_raises_message
+
+# create fake parsetree classes which are constructed
+# exactly as the repr() of a real parsetree object.
+# this allows us to use a Python construct as the source
+# of a comparable repr(), which is also hit by the 2to3 tool.
+
+def repr_arg(x):
+    if isinstance(x, dict):
+        return util.sorted_dict_repr(x)
+    else:
+        return repr(x)
+
+from mako import parsetree
+for cls in list(parsetree.__dict__.values()):
+    if isinstance(cls, type) and \
+        issubclass(cls, parsetree.Node):
+        clsname = cls.__name__
+        exec(("""
+class %s(object):
+    def __init__(self, *args):
+        self.args = args
+    def __repr__(self):
+        return "%%s(%%s)" %% (
+            self.__class__.__name__,
+            ", ".join(repr_arg(x) for x in self.args)
+            )
+""" % clsname), locals())
+
+# NOTE: most assertion expressions were generated, then formatted
+# by PyTidy, hence the dense formatting.
+
+class LexerTest(TemplateTest):
+
+    def _compare(self, node, expected):
+        eq_(repr(node), repr(expected))
+
+    def test_text_and_tag(self):
+        template = """
+<b>Hello world</b>
+        <%def name="foo()">
+                this is a def.
+        </%def>
+        
+        and some more text.
+"""
+        node = Lexer(template).parse()
+        self._compare(node, TemplateNode({},
+                      [Text('''\n<b>Hello world</b>\n        ''', (1,
+                      1)), DefTag('def', {'name': 'foo()'}, (3, 9),
+                      [Text('''\n                this is a def.\n        ''',
+                      (3, 28))]),
+                      Text('''\n        \n        and some more text.\n''',
+                      (5, 16))]))
+
+    def test_unclosed_tag(self):
+        template = """
+        
+            <%def name="foo()">
+             other text
+        """
+        try:
+            nodes = Lexer(template).parse()
+            assert False
+        except exceptions.SyntaxException as e:
+            assert str(e) == "Unclosed tag: <%def> at line: 5 char: 9"
+
+    def test_onlyclosed_tag(self):
+        template = \
+            """
+            <%def name="foo()">
+                foo
+            </%def>
+            
+            </%namespace>
+            
+            hi.
+        """
+        self.assertRaises(exceptions.SyntaxException,
+                          Lexer(template).parse)
+
+    def test_noexpr_allowed(self):
+        template = \
+            """
+            <%namespace name="${foo}"/>
+        """
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+
+    def test_unmatched_tag(self):
+        template = \
+            """
+        <%namespace name="bar">
+        <%def name="foo()">
+            foo
+            </%namespace>
+        </%def>
+        
+        
+        hi.
+"""
+        self.assertRaises(exceptions.SyntaxException,
+                          Lexer(template).parse)
+
+    def test_nonexistent_tag(self):
+        template = """
+            <%lala x="5"/>
+        """
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+
+    def test_wrongcase_tag(self):
+        template = \
+            """
+            <%DEF name="foo()">
+            </%def>
+        
+        """
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+
+    def test_percent_escape(self):
+        template = \
+            """
+        
+%% some whatever.
+
+    %% more some whatever
+    % if foo:
+    % endif
+        """
+        node = Lexer(template).parse()
+        self._compare(node, TemplateNode({}, [Text('''\n        \n''',
+                      (1, 1)), Text('''% some whatever.\n\n''', (3, 2)),
+                      Text('   %% more some whatever\n', (5, 2)),
+                      ControlLine('if', 'if foo:', False, (6, 1)),
+                      ControlLine('if', 'endif', True, (7, 1)),
+                      Text('        ', (8, 1))]))
+
+    def test_text_tag(self):
+        template = \
+            """
+        ## comment
+        % if foo:
+            hi
+        % endif
+        <%text>
+            # more code
+            
+            % more code
+            <%illegal compionent>/></>
+            <%def name="laal()">def</%def>
+            
+            
+        </%text>
+
+        <%def name="foo()">this is foo</%def>
+        
+        % if bar:
+            code
+        % endif
+        """
+        node = Lexer(template).parse()
+        self._compare(node, 
+            TemplateNode({}, [Text('\n', (1, 1)),
+              Comment('comment', (2, 1)), 
+              ControlLine('if', 'if foo:', False, (3, 1)),
+              Text('            hi\n', (4, 1)),
+              ControlLine('if', 'endif', True, (5, 1)),
+              Text('        ', (6, 1)), TextTag('text', {},
+              (6, 9),
+              [Text('''\n            # more code\n            '''
+              '''\n            % more code\n            '''
+              '''<%illegal compionent>/></>\n            '''
+              '''<%def name="laal()">def</%def>\n       '''
+              '''     \n            \n        ''',
+                      (6, 16))]), Text('''
+
+        ''', (14, 17)),
+                      DefTag('def', {'name': 'foo()'}, (16, 9),
+                      [Text('this is foo', (16, 28))]),
+                      Text('''\n        \n''', (16, 46)),
+                      ControlLine('if', 'if bar:', False, (18, 1)),
+                      Text('            code\n', (19, 1)),
+                      ControlLine('if', 'endif', True, (20, 1)),
+                      Text('        ', (21, 1))]))
+
+    def test_def_syntax(self):
+        template = \
+            """
+        <%def lala>
+            hi
+        </%def>
+"""
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+
+    def test_def_syntax_2(self):
+        template = \
+            """
+        <%def name="lala">
+            hi
+        </%def>
+    """
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+
+    def test_whitespace_equals(self):
+        template = \
+            """
+            <%def name = "adef()" >
+              adef
+            </%def>
+        """
+        node = Lexer(template).parse()
+        self._compare(node, TemplateNode({}, [Text('\n            ',
+                      (1, 1)), DefTag('def', {'name': 'adef()'}, (2,
+                      13),
+                      [Text('''\n              adef\n            ''',
+                      (2, 36))]), Text('\n        ', (4, 20))]))
+
+    def test_ns_tag_closed(self):
+        template = \
+            """
+        
+            <%self:go x="1" y="2" z="${'hi' + ' ' + 'there'}"/>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''
+        
+            ''', (1, 1)),
+                      CallNamespaceTag('self:go', {'x': '1', 'y'
+                      : '2', 'z': "${'hi' + ' ' + 'there'}"}, (3,
+                      13), []), Text('\n        ', (3, 64))]))
+
+    def test_ns_tag_empty(self):
+        template = \
+            """
+            <%form:option value=""></%form:option>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n            ',
+                      (1, 1)), CallNamespaceTag('form:option',
+                      {'value': ''}, (2, 13), []), Text('\n        '
+                      , (2, 51))]))
+
+    def test_ns_tag_open(self):
+        template = \
+            """
+        
+            <%self:go x="1" y="${process()}">
+                this is the body
+            </%self:go>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''
+        
+            ''', (1, 1)),
+                      CallNamespaceTag('self:go', {'x': '1', 'y'
+                      : '${process()}'}, (3, 13),
+                      [Text('''
+                this is the body
+            ''',
+                      (3, 46))]), Text('\n        ', (5, 24))]))
+
+    def test_expr_in_attribute(self):
+        """test some slightly trickier expressions.
+        
+        you can still trip up the expression parsing, though, unless we
+        integrated really deeply somehow with AST."""
+
+        template = \
+            """
+            <%call expr="foo>bar and 'lala' or 'hoho'"/>
+            <%call expr='foo<bar and hoho>lala and "x" + "y"'/>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n            ',
+                      (1, 1)), CallTag('call', {'expr'
+                      : "foo>bar and 'lala' or 'hoho'"}, (2, 13), []),
+                      Text('\n            ', (2, 57)), CallTag('call'
+                      , {'expr': 'foo<bar and hoho>lala and "x" + "y"'
+                      }, (3, 13), []), Text('\n        ', (3, 64))]))
+
+    def test_pagetag(self):
+        template = \
+            """
+            <%page cached="True", args="a, b"/>
+            
+            some template
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n            ',
+                      (1, 1)), PageTag('page', {'args': 'a, b',
+                      'cached': 'True'}, (2, 13), []),
+                      Text('''
+            
+            some template
+        ''',
+                      (2, 48))]))
+
+    def test_nesting(self):
+        template = \
+            """
+        
+        <%namespace name="ns">
+            <%def name="lala(hi, there)">
+                <%call expr="something()"/>
+            </%def>
+        </%namespace>
+        
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''
+        
+        ''', (1, 1)),
+                      NamespaceTag('namespace', {'name': 'ns'}, (3,
+                      9), [Text('\n            ', (3, 31)),
+                      DefTag('def', {'name': 'lala(hi, there)'}, (4,
+                      13), [Text('\n                ', (4, 42)),
+                      CallTag('call', {'expr': 'something()'}, (5,
+                      17), []), Text('\n            ', (5, 44))]),
+                      Text('\n        ', (6, 20))]),
+                      Text('''
+        
+        ''', (7, 22))]))
+
+    if util.py3k:
+        def test_code(self):
+            template = \
+"""text
+    <%
+        print("hi")
+        for x in range(1,5):
+            print(x)
+    %>
+more text
+    <%!
+        import foo
+    %>
+"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, 
+            TemplateNode({}, [
+                Text('text\n    ', (1, 1)), 
+                Code('\nprint("hi")\nfor x in range(1,5):\n    '
+                            'print(x)\n    \n', False, (2, 5)), 
+                Text('\nmore text\n    ', (6, 7)), 
+                Code('\nimport foo\n    \n', True, (8, 5)), 
+                Text('\n', (10, 7))])
+            )
+
+
+    else:
+
+        def test_code(self):
+            template = \
+"""text
+    <%
+        print "hi"
+        for x in range(1,5):
+            print x
+    %>
+more text
+    <%!
+        import foo
+    %>
+"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, 
+            TemplateNode({}, [
+                Text('text\n    ', (1, 1)), 
+                Code('\nprint "hi"\nfor x in range(1,5):\n    '
+                            'print x\n    \n', False, (2, 5)), 
+                Text('\nmore text\n    ', (6, 7)), 
+                Code('\nimport foo\n    \n', True, (8, 5)), 
+                Text('\n', (10, 7))])
+            )
+
+    def test_code_and_tags(self):
+        template = \
+            """
+<%namespace name="foo">
+    <%def name="x()">
+        this is x
+    </%def>
+    <%def name="y()">
+        this is y
+    </%def>
+</%namespace>
+
+<%
+    result = []
+    data = get_data()
+    for x in data:
+        result.append(x+7)
+%>
+
+    result: <%call expr="foo.x(result)"/>
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)),
+                      NamespaceTag('namespace', {'name': 'foo'}, (2,
+                      1), [Text('\n    ', (2, 24)), DefTag('def',
+                      {'name': 'x()'}, (3, 5),
+                      [Text('''\n        this is x\n    ''', (3, 22))]),
+                      Text('\n    ', (5, 12)), DefTag('def', {'name'
+                      : 'y()'}, (6, 5),
+                      [Text('''\n        this is y\n    ''', (6, 22))]),
+                      Text('\n', (8, 12))]), Text('''\n\n''', (9, 14)),
+                      Code('''\nresult = []\ndata = get_data()\n'''
+                      '''for x in data:\n    result.append(x+7)\n\n''',
+                      False, (11, 1)), Text('''\n\n    result: ''', (16,
+                      3)), CallTag('call', {'expr': 'foo.x(result)'
+                      }, (18, 13), []), Text('\n', (18, 42))]))
+
+    def test_expression(self):
+        template = \
+            """
+        this is some ${text} and this is ${textwith | escapes, moreescapes}
+        <%def name="hi()">
+            give me ${foo()} and ${bar()}
+        </%def>
+        ${hi()}
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('\n        this is some ', (1, 1)),
+                      Expression('text', [], (2, 22)),
+                      Text(' and this is ', (2, 29)),
+                      Expression('textwith ', ['escapes', 'moreescapes'
+                      ], (2, 42)), Text('\n        ', (2, 76)),
+                      DefTag('def', {'name': 'hi()'}, (3, 9),
+                      [Text('\n            give me ', (3, 27)),
+                      Expression('foo()', [], (4, 21)), Text(' and ',
+                      (4, 29)), Expression('bar()', [], (4, 34)),
+                      Text('\n        ', (4, 42))]), Text('\n        '
+                      , (5, 16)), Expression('hi()', [], (6, 9)),
+                      Text('\n', (6, 16))]))
+
+
+    def test_tricky_expression(self):
+        template = """
+        
+            ${x and "|" or "hi"}
+        """
+        nodes = Lexer(template).parse()
+        self._compare(
+            nodes,
+            TemplateNode({}, [
+                Text('\n        \n            ', (1, 1)), 
+                Expression('x and "|" or "hi"', [], (3, 13)), 
+                Text('\n        ', (3, 33))
+            ])
+        )
+
+        template = """
+        
+            ${hello + '''heres '{|}' text | | }''' | escape1}
+        """
+        nodes = Lexer(template).parse()
+        self._compare(
+            nodes,
+            TemplateNode({}, [
+                Text('\n        \n            ', (1, 1)), 
+                Expression("hello + '''heres '{|}' text | | }''' ", 
+                                ['escape1'], (3, 13)), 
+                Text('\n        ', (3, 62))
+            ])
+        )
+
+    def test_tricky_code(self):
+        if util.py3k:
+            template = """<% print('hi %>') %>"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, TemplateNode({},
+                          [Code("print('hi %>') \n", False, (1, 1))]))
+        else:
+            template = """<% print 'hi %>' %>"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, TemplateNode({},
+                          [Code("print 'hi %>' \n", False, (1, 1))]))
+
+    def test_tricky_code_2(self):
+        template = \
+            """<% 
+        # someone's comment
+        %>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Code(""" 
+        # someone's comment
+        
+""",
+                      False, (1, 1)), Text('\n        ', (3, 11))]))
+
+    if util.py3k:
+        def test_tricky_code_3(self):
+            template = \
+                """<%
+            print('hi')
+            # this is a comment
+            # another comment
+            x = 7 # someone's '''comment
+            print('''
+        there
+        ''')
+            # someone else's comment
+        %> '''and now some text '''"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, TemplateNode({},
+                          [Code("""
+print('hi')
+# this is a comment
+# another comment
+x = 7 # someone's '''comment
+print('''
+        there
+        ''')
+# someone else's comment
+        
+""",
+                          False, (1, 1)),
+                          Text(" '''and now some text '''", (10,
+                          11))]))
+    else:
+        def test_tricky_code_3(self):
+            template = \
+                """<%
+            print 'hi'
+            # this is a comment
+            # another comment
+            x = 7 # someone's '''comment
+            print '''
+        there
+        '''
+            # someone else's comment
+        %> '''and now some text '''"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, TemplateNode({},
+                      [Code("""\nprint 'hi'\n# this is a comment\n"""
+                      """# another comment\nx = 7 """
+                      """# someone's '''comment\nprint '''\n        """
+                      """there\n        '''\n# someone else's """
+                      """comment\n        \n""",
+                      False, (1, 1)),
+                      Text(" '''and now some text '''", (10,11))]))
+
+    def test_tricky_code_4(self):
+        template = \
+            """<% foo = "\\"\\\\" %>"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Code("""foo = "\\"\\\\" \n""",
+                      False, (1, 1))]))
+
+    def test_tricky_code_5(self):
+        template = \
+            """before ${ {'key': 'value'} } after"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('before ', (1, 1)),
+                      Expression(" {'key': 'value'} ", [], (1, 8)),
+                      Text(' after', (1, 29))]))
+
+    def test_control_lines(self):
+        template = \
+            """
+text text la la
+% if foo():
+ mroe text la la blah blah
+% endif
+
+        and osme more stuff
+        % for l in range(1,5):
+    tex tesl asdl l is ${l} kfmas d
+      % endfor
+    tetx text
+    
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''\ntext text la la\n''', (1, 1)),
+                      ControlLine('if', 'if foo():', False, (3, 1)),
+                      Text(' mroe text la la blah blah\n', (4, 1)),
+                      ControlLine('if', 'endif', True, (5, 1)),
+                      Text('''\n        and osme more stuff\n''', (6,
+                      1)), ControlLine('for', 'for l in range(1,5):',
+                      False, (8, 1)), Text('    tex tesl asdl l is ',
+                      (9, 1)), Expression('l', [], (9, 24)),
+                      Text(' kfmas d\n', (9, 28)), ControlLine('for',
+                      'endfor', True, (10, 1)),
+                      Text('''    tetx text\n    \n''', (11, 1))]))
+
+    def test_control_lines_2(self):
+        template = \
+"""% for file in requestattr['toc'].filenames:
+    x
+% endfor
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [ControlLine('for',
+                      "for file in requestattr['toc'].filenames:",
+                      False, (1, 1)), Text('    x\n', (2, 1)),
+                      ControlLine('for', 'endfor', True, (3, 1))]))
+
+    def test_long_control_lines(self):
+        template = \
+        """
+    % for file in \\
+        requestattr['toc'].filenames:
+        x
+    % endfor
+        """
+        nodes = Lexer(template).parse()
+        self._compare(
+            nodes,
+            TemplateNode({}, [
+                Text('\n', (1, 1)), 
+                ControlLine('for', "for file in \\\n        "
+                                "requestattr['toc'].filenames:", 
+                                False, (2, 1)), 
+                Text('        x\n', (4, 1)), 
+                ControlLine('for', 'endfor', True, (5, 1)), 
+                Text('        ', (6, 1))
+            ])
+        )
+
+    def test_unmatched_control(self):
+        template = """
+
+        % if foo:
+            % for x in range(1,5):
+        % endif
+"""
+        assert_raises_message(
+            exceptions.SyntaxException,
+            "Keyword 'endif' doesn't match keyword 'for' at line: 5 char: 1",
+            Lexer(template).parse
+        )
+
+    def test_unmatched_control_2(self):
+        template = """
+
+        % if foo:
+            % for x in range(1,5):
+            % endfor
+"""
+
+        assert_raises_message(
+            exceptions.SyntaxException,
+            "Unterminated control keyword: 'if' at line: 3 char: 1",
+            Lexer(template).parse
+        )
+
+    def test_unmatched_control_3(self):
+        template = """
+
+        % if foo:
+            % for x in range(1,5):
+            % endlala
+        % endif
+"""
+        assert_raises_message(
+            exceptions.SyntaxException,
+            "Keyword 'endlala' doesn't match keyword 'for' at line: 5 char: 1",
+            Lexer(template).parse
+        )
+
+    def test_ternary_control(self):
+        template = \
+            """
+        % if x:
+            hi
+        % elif y+7==10:
+            there
+        % elif lala:
+            lala
+        % else:
+            hi
+        % endif
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)),
+                      ControlLine('if', 'if x:', False, (2, 1)),
+                      Text('            hi\n', (3, 1)),
+                      ControlLine('elif', 'elif y+7==10:', False, (4,
+                      1)), Text('            there\n', (5, 1)),
+                      ControlLine('elif', 'elif lala:', False, (6,
+                      1)), Text('            lala\n', (7, 1)),
+                      ControlLine('else', 'else:', False, (8, 1)),
+                      Text('            hi\n', (9, 1)),
+                      ControlLine('if', 'endif', True, (10, 1))]))
+
+    def test_integration(self):
+        template = \
+            """<%namespace name="foo" file="somefile.html"/>
+ ## inherit from foobar.html
+<%inherit file="foobar.html"/>
+
+<%def name="header()">
+     <div>header</div>
+</%def>
+<%def name="footer()">
+    <div> footer</div>
+</%def>
+
+<table>
+    % for j in data():
+    <tr>
+        % for x in j:
+            <td>Hello ${x| h}</td>
+        % endfor
+    </tr>
+    % endfor
+</table>
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [NamespaceTag('namespace'
+                      , {'file': 'somefile.html', 'name': 'foo'},
+                      (1, 1), []), Text('\n', (1, 46)),
+                      Comment('inherit from foobar.html', (2, 1)),
+                      InheritTag('inherit', {'file': 'foobar.html'},
+                      (3, 1), []), Text('''\n\n''', (3, 31)),
+                      DefTag('def', {'name': 'header()'}, (5, 1),
+                      [Text('''\n     <div>header</div>\n''', (5,
+                      23))]), Text('\n', (7, 8)), DefTag('def',
+                      {'name': 'footer()'}, (8, 1),
+                      [Text('''\n    <div> footer</div>\n''', (8,
+                      23))]), Text('''\n\n<table>\n''', (10, 8)),
+                      ControlLine('for', 'for j in data():', False,
+                      (13, 1)), Text('    <tr>\n', (14, 1)),
+                      ControlLine('for', 'for x in j:', False, (15,
+                      1)), Text('            <td>Hello ', (16, 1)),
+                      Expression('x', ['h'], (16, 23)), Text('</td>\n'
+                      , (16, 30)), ControlLine('for', 'endfor', True,
+                      (17, 1)), Text('    </tr>\n', (18, 1)),
+                      ControlLine('for', 'endfor', True, (19, 1)),
+                      Text('</table>\n', (20, 1))]))
+
+    def test_comment_after_statement(self):
+        template = \
+            """
+        % if x: #comment
+            hi
+        % else: #next
+            hi
+        % endif #end
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)),
+                      ControlLine('if', 'if x: #comment', False, (2,
+                      1)), Text('            hi\n', (3, 1)),
+                      ControlLine('else', 'else: #next', False, (4,
+                      1)), Text('            hi\n', (5, 1)),
+                      ControlLine('if', 'endif #end', True, (6, 1))]))
+
+    def test_crlf(self):
+        template = open(self._file_path("crlf.html"), 'rb').read()
+        nodes = Lexer(template).parse()
+        self._compare(
+            nodes,
+            TemplateNode({}, [
+                Text('<html>\r\n\r\n', (1, 1)), 
+                PageTag('page', {
+                            'args': "a=['foo',\n                'bar']"
+                        }, (3, 1), []), 
+                Text('\r\n\r\nlike the name says.\r\n\r\n', (4, 26)), 
+                ControlLine('for', 'for x in [1,2,3]:', False, (8, 1)), 
+                Text('        ', (9, 1)), 
+                Expression('x', [], (9, 9)), 
+                ControlLine('for', 'endfor', True, (10, 1)), 
+                Text('\r\n', (11, 1)), 
+                Expression("trumpeter == 'Miles' and "
+                                "trumpeter or \\\n      'Dizzy'", 
+                                [], (12, 1)), 
+                Text('\r\n\r\n', (13, 15)), 
+                DefTag('def', {'name': 'hi()'}, (15, 1), [
+                    Text('\r\n    hi!\r\n', (15, 19))]), 
+                    Text('\r\n\r\n</html>\r\n', (17, 8))
+                ])
+        )
+        assert flatten_result(Template(template).render()) \
+            == """<html> like the name says. 1 2 3 Dizzy </html>"""
+
+    def test_comments(self):
+        template = \
+            """
+<style>
+ #someselector
+ # other non comment stuff
+</style>
+## a comment
+
+# also not a comment
+
+   ## this is a comment
+   
+this is ## not a comment
+
+<%doc> multiline
+comment
+</%doc>
+
+hi
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''\n<style>\n #someselector\n # '''
+                        '''other non comment stuff\n</style>\n''',
+                      (1, 1)), Comment('a comment', (6, 1)),
+                      Text('''\n# also not a comment\n\n''', (7, 1)),
+                      Comment('this is a comment', (10, 1)),
+                      Text('''   \nthis is ## not a comment\n\n''', (11,
+                      1)), Comment(''' multiline\ncomment\n''', (14,
+                      1)), Text('''
+
+hi
+''', (16, 8))]))
+
+    def test_docs(self):
+        template = \
+            """
+        <%doc>
+            this is a comment
+        </%doc>
+        <%def name="foo()">
+            <%doc>
+                this is the foo func
+            </%doc>
+        </%def>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, 
+            TemplateNode({}, [Text('\n        ', (1,
+              1)),
+              Comment('''\n            this is a comment\n        ''',
+              (2, 9)), Text('\n        ', (4, 16)),
+              DefTag('def', {'name': 'foo()'}, (5, 9),
+              [Text('\n            ', (5, 28)),
+              Comment('''\n                this is the foo func\n'''
+                '''            ''',
+              (6, 13)), Text('\n        ', (8, 20))]),
+              Text('\n        ', (9, 16))]))
+
+    def test_preprocess(self):
+
+        def preproc(text):
+            return re.sub(r'(?<=\n)\s*#[^#]', '##', text)
+
+        template = \
+            """
+    hi
+    # old style comment
+# another comment
+"""
+        nodes = Lexer(template, preprocessor=preproc).parse()
+        self._compare(nodes, TemplateNode({}, [Text('''\n    hi\n''',
+                      (1, 1)), Comment('old style comment', (3, 1)),
+                      Comment('another comment', (4, 1))]))
diff --git a/lib3/Mako-0.7.3/test/test_lookup.py b/lib3/Mako-0.7.3/test/test_lookup.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_lookup.py
@@ -0,0 +1,104 @@
+from mako.template import Template
+from mako import lookup, exceptions, runtime
+from mako.util import FastEncodingBuffer
+from .util import flatten_result, result_lines
+import unittest
+import os
+
+from test import TemplateTest, template_base, module_base, assert_raises_message
+
+tl = lookup.TemplateLookup(directories=[template_base])
+class LookupTest(unittest.TestCase):
+    def test_basic(self):
+        t = tl.get_template('index.html')
+        assert result_lines(t.render()) == [
+            "this is index"
+        ]
+    def test_subdir(self):
+        t = tl.get_template('/subdir/index.html')
+        assert result_lines(t.render()) == [
+            "this is sub index",
+            "this is include 2"
+
+        ]
+
+        assert tl.get_template('/subdir/index.html').module_id \
+                            == '_subdir_index_html'
+ 
+    def test_updir(self):
+        t = tl.get_template('/subdir/foo/../bar/../index.html')
+        assert result_lines(t.render()) == [
+            "this is sub index",
+            "this is include 2"
+
+        ]
+ 
+    def test_directory_lookup(self):
+        """test that hitting an existent directory still raises
+        LookupError."""
+ 
+        self.assertRaises(exceptions.TopLevelLookupException,
+            tl.get_template, "/subdir"
+        )
+ 
+    def test_no_lookup(self):
+        t = Template("hi <%include file='foo.html'/>")
+        try:
+            t.render()
+            assert False
+        except exceptions.TemplateLookupException as e:
+            assert str(e) == \
+                "Template 'memory:%s' has no TemplateLookup associated" % \
+                hex(id(t))
+ 
+    def test_uri_adjust(self):
+        tl = lookup.TemplateLookup(directories=['/foo/bar'])
+        assert tl.filename_to_uri('/foo/bar/etc/lala/index.html') == \
+                        '/etc/lala/index.html'
+
+        tl = lookup.TemplateLookup(directories=['./foo/bar'])
+        assert tl.filename_to_uri('./foo/bar/etc/index.html') == \
+                        '/etc/index.html'
+ 
+    def test_uri_cache(self):
+        """test that the _uri_cache dictionary is available"""
+        tl._uri_cache[('foo', 'bar')] = '/some/path'
+        assert tl._uri_cache[('foo', 'bar')] == '/some/path'
+ 
+    def test_check_not_found(self):
+        tl = lookup.TemplateLookup()
+        tl.put_string("foo", "this is a template")
+        f = tl.get_template("foo")
+        assert f.uri in tl._collection
+        f.filename = "nonexistent"
+        self.assertRaises(exceptions.TemplateLookupException,
+            tl.get_template, "foo"
+        )
+        assert f.uri not in tl._collection
+
+    def test_dont_accept_relative_outside_of_root(self):
+        """test the mechanics of an include where 
+        the include goes outside of the path"""
+        tl = lookup.TemplateLookup(directories=[os.path.join(template_base, "subdir")])
+        index = tl.get_template("index.html")
+
+        ctx = runtime.Context(FastEncodingBuffer())
+        ctx._with_template=index
+
+        assert_raises_message(
+            exceptions.TemplateLookupException,
+           "Template uri \"../index.html\" is invalid - it "
+            "cannot be relative outside of the root path",
+            runtime._lookup_template, ctx, "../index.html", index.uri
+        )
+
+        assert_raises_message(
+            exceptions.TemplateLookupException,
+           "Template uri \"../othersubdir/foo.html\" is invalid - it "
+            "cannot be relative outside of the root path",
+            runtime._lookup_template, ctx, "../othersubdir/foo.html", index.uri
+        )
+
+        # this is OK since the .. cancels out
+        t = runtime._lookup_template(ctx, "foo/../index.html", index.uri)
+
diff --git a/lib3/Mako-0.7.3/test/test_loop.py b/lib3/Mako-0.7.3/test/test_loop.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_loop.py
@@ -0,0 +1,295 @@
+import re
+import unittest
+
+from mako.template import Template
+from mako.lookup import TemplateLookup
+from mako.codegen import (
+        _FOR_LOOP, mangle_mako_loop, LoopVariable
+    )
+from mako.runtime import LoopStack, LoopContext
+from mako import exceptions
+from test import assert_raises_message
+from test import TemplateTest, eq_
+from .util import flatten_result, result_lines
+
+class TestLoop(unittest.TestCase):
+
+    def test__FOR_LOOP(self):
+        for statement, target_list, expression_list in (
+                ('for x in y:', 'x', 'y'),
+                ('for x, y in z:', 'x, y', 'z'),
+                ('for (x,y) in z:', '(x,y)', 'z'),
+                ('for ( x, y, z) in a:', '( x, y, z)', 'a'),
+                ('for x in [1, 2, 3]:', 'x', '[1, 2, 3]'),
+                ('for x in "spam":', 'x', '"spam"'),
+                ('for k,v in dict(a=1,b=2).items():', 'k,v',
+                    'dict(a=1,b=2).items()'),
+                ('for x in [y+1 for y in [1, 2, 3]]:', 'x',
+                    '[y+1 for y in [1, 2, 3]]')
+                ):
+            match = _FOR_LOOP.match(statement)
+            assert match and match.groups() == (target_list, expression_list)
+
+    def test_no_loop(self):
+        template = Template("""% for x in 'spam':
+${x}
+% endfor""")
+        code = template.code
+        assert not re.match(r"loop = __M_loop._enter\(:", code), "No need to "\
+                "generate a loop context if the loop variable wasn't accessed"
+        print(template.render())
+
+    def test_loop_demo(self):
+        template = Template("""x|index|reverse_index|first|last|cycle|even|odd
+% for x in 'ham':
+${x}|${loop.index}|${loop.reverse_index}|${loop.first}|${loop.last}|${loop.cycle('even', 'odd')}|${loop.even}|${loop.odd}
+% endfor""")
+        expected = [
+                "x|index|reverse_index|first|last|cycle|even|odd",
+                "h|0|2|True|False|even|True|False",
+                "a|1|1|False|False|odd|False|True",
+                "m|2|0|False|True|even|True|False"
+            ]
+        code = template.code
+        assert "loop = __M_loop._enter(" in code, "Generated a loop context since "\
+                "the loop variable was accessed"
+        rendered = template.render()
+        print(rendered)
+        for line in expected:
+            assert line in rendered, "Loop variables give information about "\
+                    "the progress of the loop"
+
+    def test_nested_loops(self):
+        template = Template("""% for x in 'ab':
+${x} ${loop.index} <- start in outer loop
+% for y in [0, 1]:
+${y} ${loop.index} <- go to inner loop
+% endfor
+${x} ${loop.index} <- back to outer loop
+% endfor""")
+        code = template.code
+        rendered = template.render()
+        expected = [
+                "a 0 <- start in outer loop",
+                "0 0 <- go to inner loop",
+                "1 1 <- go to inner loop",
+                "a 0 <- back to outer loop",
+                "b 1 <- start in outer loop",
+                "0 0 <- go to inner loop",
+                "1 1 <- go to inner loop",
+                "b 1 <- back to outer loop",
+            ]
+        for line in expected:
+            assert line in rendered, "The LoopStack allows you to take "\
+                    "advantage of the loop variable even in embedded loops"
+
+    def test_parent_loops(self):
+        template = Template("""% for x in 'ab':
+${x} ${loop.index} <- outer loop
+% for y in [0, 1]:
+${y} ${loop.index} <- inner loop
+${x} ${loop.parent.index} <- parent loop
+% endfor
+${x} ${loop.index} <- outer loop
+% endfor""")
+        code = template.code
+        rendered = template.render()
+        expected = [
+                "a 0 <- outer loop",
+                "a 0 <- parent loop",
+                "b 1 <- outer loop",
+                "b 1 <- parent loop"
+            ]
+        for line in expected:
+            print(code)
+            assert line in rendered, "The parent attribute of a loop gives "\
+                    "you the previous loop context in the stack"
+
+    def test_out_of_context_access(self):
+        template = Template("""${loop.index}""")
+        assert_raises_message(
+            exceptions.RuntimeException,
+            "No loop context is established",
+            template.render
+        )
+
+class TestLoopStack(unittest.TestCase):
+
+    def setUp(self):
+        self.stack = LoopStack()
+        self.bottom = 'spam'
+        self.stack.stack = [self.bottom]
+
+    def test_enter(self):
+        iterable = 'ham'
+        s = self.stack._enter(iterable)
+        assert s is self.stack.stack[-1], "Calling the stack with an iterable returns "\
+                "the stack"
+        assert iterable == self.stack.stack[-1]._iterable, "and pushes the "\
+                "iterable on the top of the stack"
+
+    def test__top(self):
+        assert self.bottom == self.stack._top, "_top returns the last item "\
+                "on the stack"
+
+    def test__pop(self):
+        assert len(self.stack.stack) == 1
+        top = self.stack._pop()
+        assert top == self.bottom
+        assert len(self.stack.stack) == 0
+
+    def test__push(self):
+        assert len(self.stack.stack) == 1
+        iterable = 'ham'
+        self.stack._push(iterable)
+        assert len(self.stack.stack) == 2
+        assert iterable is self.stack._top._iterable
+
+    def test_exit(self):
+        iterable = 'ham'
+        self.stack._enter(iterable)
+        before = len(self.stack.stack)
+        self.stack._exit()
+        after = len(self.stack.stack)
+        assert before == (after + 1), "Exiting a context pops the stack"
+
+
+class TestLoopContext(unittest.TestCase):
+
+    def setUp(self):
+        self.iterable = [1, 2, 3]
+        self.ctx = LoopContext(self.iterable)
+
+    def test___len__(self):
+        assert len(self.iterable) == len(self.ctx), "The LoopContext is the "\
+                "same length as the iterable"
+
+    def test_index(self):
+        expected = tuple(range(len(self.iterable)))
+        actual = tuple(self.ctx.index for i in self.ctx)
+        assert expected == actual, "The index is consistent with the current "\
+                "iteration count"
+
+    def test_reverse_index(self):
+        length = len(self.iterable)
+        expected = tuple([length-i-1 for i in range(length)])
+        actual = tuple(self.ctx.reverse_index for i in self.ctx)
+        print(expected, actual)
+        assert expected == actual, "The reverse_index is the number of "\
+                "iterations until the end"
+
+    def test_first(self):
+        expected = (True, False, False)
+        actual = tuple(self.ctx.first for i in self.ctx)
+        assert expected == actual, "first is only true on the first iteration"
+
+    def test_last(self):
+        expected = (False, False, True)
+        actual = tuple(self.ctx.last for i in self.ctx)
+        assert expected == actual, "last is only true on the last iteration"
+
+    def test_even(self):
+        expected = (True, False, True)
+        actual = tuple(self.ctx.even for i in self.ctx)
+        assert expected == actual, "even is true on even iterations"
+
+    def test_odd(self):
+        expected = (False, True, False)
+        actual = tuple(self.ctx.odd for i in self.ctx)
+        assert expected == actual, "odd is true on odd iterations"
+
+    def test_cycle(self):
+        expected = ('a', 'b', 'a')
+        actual = tuple(self.ctx.cycle('a', 'b') for i in self.ctx)
+        assert expected == actual, "cycle endlessly cycles through the values"
+
+class TestLoopFlags(TemplateTest):
+    def test_loop_disabled_template(self):
+        self._do_memory_test(
+        """
+            the loop: ${loop}
+        """, 
+        "the loop: hi",
+        template_args=dict(loop='hi'),
+        filters=flatten_result,
+        enable_loop=False
+        )
+
+    def test_loop_disabled_lookup(self):
+        l = TemplateLookup(enable_loop=False)
+        l.put_string("x",
+        """
+            the loop: ${loop}
+        """
+        )
+
+        self._do_test(
+            l.get_template("x"),
+            "the loop: hi",
+            template_args=dict(loop='hi'),
+            filters=flatten_result,
+        )
+
+    def test_loop_disabled_override_template(self):
+        self._do_memory_test(
+        """
+            <%page enable_loop="True" />
+            % for i in (1, 2, 3):
+                ${i} ${loop.index}
+            % endfor
+        """, 
+        "1 0 2 1 3 2",
+        template_args=dict(loop='hi'),
+        filters=flatten_result,
+        enable_loop=False
+        )
+
+    def test_loop_disabled_override_lookup(self):
+        l = TemplateLookup(enable_loop=False)
+        l.put_string("x",
+        """
+            <%page enable_loop="True" />
+            % for i in (1, 2, 3):
+                ${i} ${loop.index}
+            % endfor
+        """
+        )
+
+        self._do_test(
+            l.get_template("x"),
+            "1 0 2 1 3 2",
+            template_args=dict(loop='hi'),
+            filters=flatten_result,
+        )
+
+    def test_loop_enabled_override_template(self):
+        self._do_memory_test(
+        """
+            <%page enable_loop="True" />
+            % for i in (1, 2, 3):
+                ${i} ${loop.index}
+            % endfor
+        """, 
+        "1 0 2 1 3 2",
+        template_args=dict(),
+        filters=flatten_result,
+        )
+
+    def test_loop_enabled_override_lookup(self):
+        l = TemplateLookup()
+        l.put_string("x",
+        """
+            <%page enable_loop="True" />
+            % for i in (1, 2, 3):
+                ${i} ${loop.index}
+            % endfor
+        """
+        )
+
+        self._do_test(
+            l.get_template("x"),
+            "1 0 2 1 3 2",
+            template_args=dict(),
+            filters=flatten_result,
+        )
+
diff --git a/lib3/Mako-0.7.3/test/test_lru.py b/lib3/Mako-0.7.3/test/test_lru.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_lru.py
@@ -0,0 +1,111 @@
+from mako.util import LRUCache
+import string, unittest, time, random
+
+import _thread
+
+class item:
+    def __init__(self, id):
+        self.id = id
+
+    def __str__(self):
+        return "item id %d" % self.id
+
+class LRUTest(unittest.TestCase):
+
+
+    def testlru(self): 
+        l = LRUCache(10, threshold=.2)
+ 
+        for id in range(1,20):
+            l[id] = item(id)
+ 
+        # first couple of items should be gone
+        self.assert_(1 not in l) 
+        self.assert_(2 not in l)
+ 
+        # next batch over the threshold of 10 should be present
+        for id in range(11,20):
+            self.assert_(id in l)
+
+        l[12]
+        l[15]
+        l[23] = item(23)
+        l[24] = item(24)
+        l[25] = item(25)
+        l[26] = item(26)
+        l[27] = item(27)
+
+        self.assert_(11 not in l)
+        self.assert_(13 not in l)
+ 
+        for id in (25, 24, 23, 14, 12, 19, 18, 17, 16, 15):
+            self.assert_(id in l) 
+
+    def _disabled_test_threaded(self):
+        size = 100
+        threshold = .5
+        all_elems = 2000
+        hot_zone = list(range(30,40))
+        cache = LRUCache(size, threshold)
+ 
+        # element to store
+        class Element(object):
+            def __init__(self, id):
+                self.id = id
+                self.regets = 0
+ 
+        # return an element.  we will favor ids in the relatively small
+        # "hot zone" 25% of  the time.
+        def get_elem():
+            if random.randint(1,4) == 1:
+                return hot_zone[random.randint(0, len(hot_zone) - 1)]
+            else:
+                return random.randint(1, all_elems)
+ 
+        total = [0]
+        # request thread.
+        def request_elem():
+            while True:
+                total[0] += 1
+                id = get_elem()
+                try:
+                    elem = cache[id]
+                    elem.regets += 1
+                except KeyError:
+                    e = Element(id)
+                    cache[id] = e
+ 
+                time.sleep(random.random() / 1000)
+
+        for x in range(0,20):
+            _thread.start_new_thread(request_elem, ())
+ 
+        # assert size doesn't grow unbounded, doesnt shrink well below size
+        for x in range(0,5):
+            time.sleep(1)
+            print("size:", len(cache))
+            assert len(cache) < size + size * threshold * 2
+            assert len(cache) > size - (size * .1)
+ 
+        # computs the average number of times a range of elements were "reused",
+        # i.e. without being removed from the cache.
+        def average_regets_in_range(start, end):
+            elem = [e for e in list(cache.values()) if e.id >= start and e.id <= end]
+            if len(elem) == 0:
+                return 0
+            avg = sum([e.regets for e in elem]) / len(elem)
+            return avg
+
+        hotzone_avg = average_regets_in_range(30, 40)
+        control_avg = average_regets_in_range(450,760)
+        total_avg = average_regets_in_range(0, 2000)
+ 
+        # hotzone should be way above the others
+        print("total fetches", total[0], "hotzone", \
+                                hotzone_avg, "control", \
+                                control_avg, "total", total_avg)
+ 
+        assert hotzone_avg > total_avg * 5 > control_avg * 5
+ 
+ 
+
diff --git a/lib3/Mako-0.7.3/test/test_namespace.py b/lib3/Mako-0.7.3/test/test_namespace.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_namespace.py
@@ -0,0 +1,792 @@
+from mako.template import Template
+from mako import lookup
+from .util import flatten_result, result_lines
+from test import TemplateTest, eq_
+
+class NamespaceTest(TemplateTest):
+    def test_inline_crossreference(self):
+        self._do_memory_test(
+            """
+            <%namespace name="x">
+                <%def name="a()">
+                    this is x a
+                </%def>
+                <%def name="b()">
+                    this is x b, and heres ${a()}
+                </%def>
+            </%namespace>
+ 
+            ${x.a()}
+ 
+            ${x.b()}
+    """,
+            "this is x a this is x b, and heres this is x a",
+            filters=flatten_result
+        )
+
+    def test_inline_assignment(self):
+        self._do_memory_test(
+            """
+            <%namespace name="x">
+                <%def name="a()">
+                    <%
+                        x = 5
+                    %>
+                    this is x: ${x}
+                </%def>
+            </%namespace>
+
+            ${x.a()}
+
+    """,
+            "this is x: 5",
+            filters=flatten_result
+        )
+
+    def test_inline_arguments(self):
+        self._do_memory_test(
+            """
+            <%namespace name="x">
+                <%def name="a(x, y)">
+                    <%
+                        result = x * y
+                    %>
+                    result: ${result}
+                </%def>
+            </%namespace>
+
+            ${x.a(5, 10)}
+
+    """,
+            "result: 50",
+            filters=flatten_result
+        )
+
+    def test_inline_not_duped(self):
+        self._do_memory_test(
+            """
+            <%namespace name="x">
+                <%def name="a()">
+                    foo
+                </%def>
+            </%namespace>
+
+            <%
+                assert x.a is not UNDEFINED, "namespace x.a wasn't defined"
+                assert a is UNDEFINED, "name 'a' is in the body locals"
+            %>
+
+    """,
+            "",
+            filters=flatten_result
+        )
+
+    def test_dynamic(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('a', """
+        <%namespace name="b" file="${context['b_def']}"/>
+
+        a.  b: ${b.body()}
+""")
+
+        collection.put_string('b', """
+        b.
+""")
+
+        eq_(
+            flatten_result(collection.get_template('a').render(b_def='b')),
+            "a. b: b."
+        )
+ 
+    def test_template(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" file="defs.html"/>
+ 
+        this is main.  ${comp.def1("hi")}
+        ${comp.def2("there")}
+""")
+
+        collection.put_string('defs.html', """
+        <%def name="def1(s)">
+            def1: ${s}
+        </%def>
+ 
+        <%def name="def2(x)">
+            def2: ${x}
+        </%def>
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. def1: hi def2: there"
+ 
+    def test_module(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" module="test.sample_module_namespace"/>
+
+        this is main.  ${comp.foo1()}
+        ${comp.foo2("hi")}
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+
+    def test_module_2(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" module="test.foo.test_ns"/>
+
+        this is main.  ${comp.foo1()}
+        ${comp.foo2("hi")}
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+
+    def test_module_imports(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace import="*" module="test.foo.test_ns"/>
+
+        this is main.  ${foo1()}
+        ${foo2("hi")}
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+
+    def test_module_imports_2(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace import="foo1, foo2" module="test.foo.test_ns"/>
+
+        this is main.  ${foo1()}
+        ${foo2("hi")}
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+ 
+    def test_context(self):
+        """test that namespace callables get access to the current context"""
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" file="defs.html"/>
+
+        this is main.  ${comp.def1()}
+        ${comp.def2("there")}
+""")
+
+        collection.put_string('defs.html', """
+        <%def name="def1()">
+            def1: x is ${x}
+        </%def>
+
+        <%def name="def2(x)">
+            def2: x is ${x}
+        </%def>
+""")
+
+        assert flatten_result(collection.get_template('main.html').render(x="context x")) == "this is main. def1: x is context x def2: x is there"
+ 
+    def test_overload(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" file="defs.html">
+            <%def name="def1(x, y)">
+                overridden def1 ${x}, ${y}
+            </%def>
+        </%namespace>
+
+        this is main.  ${comp.def1("hi", "there")}
+        ${comp.def2("there")}
+    """)
+
+        collection.put_string('defs.html', """
+        <%def name="def1(s)">
+            def1: ${s}
+        </%def>
+
+        <%def name="def2(x)">
+            def2: ${x}
+        </%def>
+    """)
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. overridden def1 hi, there def2: there"
+
+    def test_getattr(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("main.html", """
+            <%namespace name="foo" file="ns.html"/>
+            <%
+                 if hasattr(foo, 'lala'):
+                     foo.lala()
+                 if not hasattr(foo, 'hoho'):
+                     context.write('foo has no hoho.')
+            %>
+         """)
+        collection.put_string("ns.html", """
+          <%def name="lala()">this is lala.</%def>
+        """)
+        assert flatten_result(collection.get_template("main.html").render()) == "this is lala.foo has no hoho."
+
+    def test_in_def(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("main.html", """
+            <%namespace name="foo" file="ns.html"/>
+ 
+            this is main.  ${bar()}
+            <%def name="bar()">
+                this is bar, foo is ${foo.bar()}
+            </%def>
+        """)
+ 
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+            </%def>
+        """)
+
+        assert result_lines(collection.get_template("main.html").render()) == [
+            "this is main.",
+            "this is bar, foo is" ,
+            "this is ns.html->bar"
+        ]
+
+
+    def test_in_remote_def(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("main.html", """
+            <%namespace name="foo" file="ns.html"/>
+
+            this is main.  ${bar()}
+            <%def name="bar()">
+                this is bar, foo is ${foo.bar()}
+            </%def>
+        """)
+
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+            </%def>
+        """)
+ 
+        collection.put_string("index.html", """
+            <%namespace name="main" file="main.html"/>
+ 
+            this is index
+            ${main.bar()}
+        """)
+
+        assert result_lines(collection.get_template("index.html").render()) == [ 
+            "this is index",
+            "this is bar, foo is" ,
+            "this is ns.html->bar"
+        ]
+ 
+    def test_dont_pollute_self(self):
+        # test that get_namespace() doesn't modify the original context
+        # incompatibly
+ 
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+
+        <%def name="foo()">
+        <%
+            foo = local.get_namespace("foo.html")
+        %>
+        </%def>
+
+        name: ${self.name}
+        name via bar: ${bar()}
+
+        ${next.body()}
+
+        name: ${self.name}
+        name via bar: ${bar()}
+        <%def name="bar()">
+            ${self.name}
+        </%def>
+
+
+        """)
+
+        collection.put_string("page.html", """
+        <%inherit file="base.html"/>
+
+        ${self.foo()}
+
+        hello world
+
+        """)
+
+        collection.put_string("foo.html", """<%inherit file="base.html"/>""")
+        assert result_lines(collection.get_template("page.html").render()) == [
+            "name: self:page.html",
+            "name via bar:",
+            "self:page.html",
+            "hello world",
+            "name: self:page.html",
+            "name via bar:",
+            "self:page.html"
+        ]
+ 
+    def test_inheritance(self):
+        """test namespace initialization in a base inherited template that doesnt otherwise access the namespace"""
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%namespace name="foo" file="ns.html" inheritable="True"/>
+ 
+            ${next.body()}
+""")
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+            </%def>
+        """)
+
+        collection.put_string("index.html", """
+            <%inherit file="base.html"/>
+ 
+            this is index
+            ${self.foo.bar()}
+        """)
+ 
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is index",
+            "this is ns.html->bar"
+        ]
+
+    def test_inheritance_two(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%def name="foo()">
+                base.foo
+            </%def>
+ 
+            <%def name="bat()">
+                base.bat
+            </%def>
+""")
+        collection.put_string("lib.html", """
+            <%inherit file="base.html"/>
+            <%def name="bar()">
+                lib.bar
+                ${parent.foo()}
+                ${self.foo()}
+                ${parent.bat()}
+                ${self.bat()}
+            </%def>
+ 
+            <%def name="foo()">
+                lib.foo
+            </%def>
+ 
+        """)
+
+        collection.put_string("front.html", """
+            <%namespace name="lib" file="lib.html"/>
+            ${lib.bar()}
+        """)
+
+        assert result_lines(collection.get_template("front.html").render()) == ['lib.bar', 'base.foo', 'lib.foo', 'base.bat', 'base.bat']
+
+    def test_attr(self):
+        l = lookup.TemplateLookup()
+
+        l.put_string("foo.html", """
+        <%!
+            foofoo = "foo foo"
+            onlyfoo = "only foo"
+        %>
+        <%inherit file="base.html"/>
+        <%def name="setup()">
+            <%
+            self.attr.foolala = "foo lala"
+            %>
+        </%def>
+        ${self.attr.basefoo}
+        ${self.attr.foofoo}
+        ${self.attr.onlyfoo}
+        ${self.attr.lala}
+        ${self.attr.foolala}
+        """)
+
+        l.put_string("base.html", """
+        <%!
+            basefoo = "base foo 1"
+            foofoo = "base foo 2"
+        %>
+        <%
+            self.attr.lala = "base lala"
+        %>
+ 
+        ${self.attr.basefoo}
+        ${self.attr.foofoo}
+        ${self.attr.onlyfoo}
+        ${self.attr.lala}
+        ${self.setup()}
+        ${self.attr.foolala}
+        body
+        ${self.body()}
+        """)
+
+        assert result_lines(l.get_template("foo.html").render()) == [
+            "base foo 1",
+            "foo foo",
+            "only foo",
+            "base lala",
+            "foo lala",
+            "body",
+            "base foo 1",
+            "foo foo",
+            "only foo",
+            "base lala",
+            "foo lala",
+        ]
+ 
+    def test_attr_raise(self):
+        l = lookup.TemplateLookup()
+
+        l.put_string("foo.html", """
+            <%def name="foo()">
+            </%def>
+        """)
+
+        l.put_string("bar.html", """
+        <%namespace name="foo" file="foo.html"/>
+ 
+        ${foo.notfoo()}
+        """)
+
+        self.assertRaises(AttributeError, l.get_template("bar.html").render)
+ 
+    def test_custom_tag_1(self):
+        template = Template("""
+ 
+            <%def name="foo(x, y)">
+                foo: ${x} ${y}
+            </%def>
+ 
+            <%self:foo x="5" y="${7+8}"/>
+        """)
+        assert result_lines(template.render()) == ['foo: 5 15']
+
+    def test_custom_tag_2(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%def name="foo(x, y)">
+                foo: ${x} ${y}
+            </%def>
+ 
+            <%def name="bat(g)"><%
+                return "the bat! %s" % g
+            %></%def>
+ 
+            <%def name="bar(x)">
+                ${caller.body(z=x)}
+            </%def>
+        """)
+ 
+        collection.put_string("index.html", """
+            <%namespace name="myns" file="base.html"/>
+ 
+            <%myns:foo x="${'some x'}" y="some y"/>
+ 
+            <%myns:bar x="${myns.bat(10)}" args="z">
+                record: ${z}
+            </%myns:bar>
+ 
+        """)
+ 
+        assert result_lines(collection.get_template("index.html").render()) == [
+            'foo: some x some y', 
+            'record: the bat! 10'
+        ]
+ 
+    def test_custom_tag_3(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%namespace name="foo" file="ns.html" inheritable="True"/>
+
+            ${next.body()}
+    """)
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+                caller body: ${caller.body()}
+            </%def>
+        """)
+
+        collection.put_string("index.html", """
+            <%inherit file="base.html"/>
+
+            this is index
+            <%self.foo:bar>
+                call body
+            </%self.foo:bar>
+        """)
+ 
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is index",
+            "this is ns.html->bar",
+            "caller body:",
+            "call body"
+        ]
+ 
+    def test_custom_tag_case_sensitive(self):
+        t = Template("""
+        <%def name="renderPanel()">
+            panel ${caller.body()}
+        </%def>
+
+        <%def name="renderTablePanel()">
+            <%self:renderPanel>
+                hi
+            </%self:renderPanel>
+        </%def>
+ 
+        <%self:renderTablePanel/>
+        """)
+        assert result_lines(t.render()) == ['panel', 'hi']
+ 
+ 
+    def test_expr_grouping(self):
+        """test that parenthesis are placed around string-embedded expressions."""
+ 
+        template = Template("""
+            <%def name="bar(x, y)">
+                ${x}
+                ${y}
+            </%def>
+ 
+            <%self:bar x=" ${foo} " y="x${g and '1' or '2'}y"/>
+        """, input_encoding='utf-8')
+
+        # the concat has to come out as "x + (g and '1' or '2') + y"
+        assert result_lines(template.render(foo='this is foo', g=False)) == [
+            "this is foo",
+            "x2y"
+        ]
+
+ 
+    def test_ccall(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%namespace name="foo" file="ns.html" inheritable="True"/>
+
+            ${next.body()}
+    """)
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+                caller body: ${caller.body()}
+            </%def>
+        """)
+
+        collection.put_string("index.html", """
+            <%inherit file="base.html"/>
+
+            this is index
+            <%call expr="self.foo.bar()">
+                call body
+            </%call>
+        """)
+
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is index",
+            "this is ns.html->bar",
+            "caller body:",
+            "call body"
+        ]
+
+    def test_ccall_2(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%namespace name="foo" file="ns1.html" inheritable="True"/>
+
+            ${next.body()}
+    """)
+        collection.put_string("ns1.html", """
+            <%namespace name="foo2" file="ns2.html"/>
+            <%def name="bar()">
+                <%call expr="foo2.ns2_bar()">
+                this is ns1.html->bar
+                caller body: ${caller.body()}
+                </%call>
+            </%def>
+        """)
+
+        collection.put_string("ns2.html", """
+            <%def name="ns2_bar()">
+                this is ns2.html->bar
+                caller body: ${caller.body()}
+            </%def>
+        """)
+
+        collection.put_string("index.html", """
+            <%inherit file="base.html"/>
+
+            this is index
+            <%call expr="self.foo.bar()">
+                call body
+            </%call>
+        """)
+
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is index",
+            "this is ns2.html->bar",
+            "caller body:",
+            "this is ns1.html->bar",
+            "caller body:",
+            "call body"
+        ]
+
+    def test_import(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("functions.html","""
+            <%def name="foo()">
+                this is foo
+            </%def>
+ 
+            <%def name="bar()">
+                this is bar
+            </%def>
+ 
+            <%def name="lala()">
+                this is lala
+            </%def>
+        """)
+
+        collection.put_string("func2.html", """
+            <%def name="a()">
+                this is a
+            </%def>
+            <%def name="b()">
+                this is b
+            </%def>
+        """)
+        collection.put_string("index.html", """
+            <%namespace file="functions.html" import="*"/>
+            <%namespace file="func2.html" import="a, b"/>
+            ${foo()}
+            ${bar()}
+            ${lala()}
+            ${a()}
+            ${b()}
+            ${x}
+        """)
+
+        assert result_lines(collection.get_template("index.html").render(bar="this is bar", x="this is x")) == [
+            "this is foo",
+            "this is bar",
+            "this is lala",
+            "this is a",
+            "this is b",
+            "this is x"
+        ]
+ 
+    def test_import_calledfromdef(self):
+        l = lookup.TemplateLookup()
+        l.put_string("a", """
+        <%def name="table()">
+            im table
+        </%def>
+        """)
+
+        l.put_string("b","""
+        <%namespace file="a" import="table"/>
+
+        <%
+            def table2():
+                table()
+                return ""
+        %>
+
+        ${table2()}
+        """)
+
+        t = l.get_template("b")
+        assert flatten_result(t.render()) == "im table"
+ 
+    def test_closure_import(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("functions.html","""
+            <%def name="foo()">
+                this is foo
+            </%def>
+ 
+            <%def name="bar()">
+                this is bar
+            </%def>
+        """)
+ 
+        collection.put_string("index.html", """
+            <%namespace file="functions.html" import="*"/>
+            <%def name="cl1()">
+                ${foo()}
+            </%def>
+ 
+            <%def name="cl2()">
+                ${bar()}
+            </%def>
+ 
+            ${cl1()}
+            ${cl2()}
+        """)
+        assert result_lines(collection.get_template("index.html").render(bar="this is bar", x="this is x")) == [
+            "this is foo",
+            "this is bar",
+        ]
+
+    def test_import_local(self):
+        t = Template("""
+            <%namespace import="*">
+                <%def name="foo()">
+                    this is foo
+                </%def>
+            </%namespace>
+ 
+            ${foo()}
+ 
+        """)
+        assert flatten_result(t.render()) == "this is foo"
+ 
+    def test_ccall_import(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("functions.html","""
+            <%def name="foo()">
+                this is foo
+            </%def>
+ 
+            <%def name="bar()">
+                this is bar.
+                ${caller.body()}
+                ${caller.lala()}
+            </%def>
+        """)
+ 
+        collection.put_string("index.html", """
+            <%namespace name="func" file="functions.html" import="*"/>
+            <%call expr="bar()">
+                this is index embedded
+                foo is ${foo()}
+                <%def name="lala()">
+                     this is lala ${foo()}
+                </%def>
+            </%call>
+        """)
+        #print collection.get_template("index.html").code
+        #print collection.get_template("functions.html").code
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is bar.",
+            "this is index embedded",
+            "foo is",
+            "this is foo",
+            "this is lala",
+            "this is foo"
+        ]
diff --git a/lib3/Mako-0.7.3/test/test_pygen.py b/lib3/Mako-0.7.3/test/test_pygen.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_pygen.py
@@ -0,0 +1,252 @@
+import unittest
+
+from mako.pygen import PythonPrinter, adjust_whitespace
+from io import StringIO
+
+class GeneratePythonTest(unittest.TestCase):
+    def test_generate_normal(self):
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.writeline("import lala")
+        printer.writeline("for x in foo:")
+        printer.writeline("print x")
+        printer.writeline(None)
+        printer.writeline("print y")
+        assert stream.getvalue() == \
+"""import lala
+for x in foo:
+    print x
+print y
+"""
+    def test_generate_adjusted(self):
+        block = """
+        x = 5 +6
+        if x > 7:
+            for y in range(1,5):
+                print "<td>%s</td>" % y
+"""
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.write_indented_block(block)
+        printer.close()
+        #print stream.getvalue()
+        assert stream.getvalue() == \
+"""
+x = 5 +6
+if x > 7:
+    for y in range(1,5):
+        print "<td>%s</td>" % y
+
+"""
+    def test_generate_combo(self):
+        block = \
+"""
+                x = 5 +6
+                if x > 7:
+                    for y in range(1,5):
+                        print "<td>%s</td>" % y
+                    print "hi"
+                print "there"
+                foo(lala)
+        """
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.writeline("import lala")
+        printer.writeline("for x in foo:")
+        printer.writeline("print x")
+        printer.write_indented_block(block)
+        printer.writeline(None)
+        printer.writeline("print y")
+        printer.close()
+        #print "->" + stream.getvalue().replace(' ', '#') + "<-"
+        assert stream.getvalue() == \
+"""import lala
+for x in foo:
+    print x
+
+    x = 5 +6
+    if x > 7:
+        for y in range(1,5):
+            print "<td>%s</td>" % y
+        print "hi"
+    print "there"
+    foo(lala)
+        
+print y
+"""
+    def test_multi_line(self):
+        block = \
+"""
+    if test:
+        print ''' this is a block of stuff.
+this is more stuff in the block.
+and more block.
+'''
+        do_more_stuff(g)
+"""
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.write_indented_block(block)
+        printer.close()
+        #print stream.getvalue()
+        assert stream.getvalue() == \
+"""
+if test:
+    print ''' this is a block of stuff.
+this is more stuff in the block.
+and more block.
+'''
+    do_more_stuff(g)
+
+"""
+    
+    def test_false_unindentor(self):
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        for line in [
+            "try:",
+            "elsemyvar = 12",
+            "if True:",
+            "print 'hi'",
+            None,
+            "finally:",
+            "dosomething",
+            None
+        ]:
+            printer.writeline(line)
+        
+        assert stream.getvalue() == \
+"""try:
+    elsemyvar = 12
+    if True:
+        print 'hi'
+finally:
+    dosomething
+"""    , stream.getvalue()
+        
+        
+    def test_backslash_line(self):
+        block = \
+"""
+            # comment
+    if test:
+        if (lala + hoho) + \\
+(foobar + blat) == 5:
+            print "hi"
+    print "more indent"
+"""
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.write_indented_block(block)
+        printer.close()
+        assert stream.getvalue() == \
+"""
+            # comment
+if test:
+    if (lala + hoho) + \\
+(foobar + blat) == 5:
+        print "hi"
+print "more indent"
+
+"""
+
+class WhitespaceTest(unittest.TestCase):
+    def test_basic(self):
+        text = """
+        for x in range(0,15):
+            print x
+        print "hi"
+        """
+        assert adjust_whitespace(text) == \
+"""
+for x in range(0,15):
+    print x
+print "hi"
+"""
+
+    def test_blank_lines(self):
+        text = """
+    print "hi"  # a comment
+    
+    # more comments
+    
+    print g
+"""
+        assert adjust_whitespace(text) == \
+"""
+print "hi"  # a comment
+
+# more comments
+
+print g
+"""
+
+    def test_open_quotes_with_pound(self):
+        text = '''
+        print """  this is text
+          # and this is text
+        # and this is too """
+'''
+        assert adjust_whitespace(text) == \
+'''
+print """  this is text
+          # and this is text
+        # and this is too """
+'''
+
+    def test_quote_with_comments(self):
+        text= """
+            print 'hi'
+            # this is a comment
+            # another comment
+            x = 7 # someone's '''comment
+            print '''
+        there
+        '''
+            # someone else's comment
+"""
+
+        assert adjust_whitespace(text) == \
+"""
+print 'hi'
+# this is a comment
+# another comment
+x = 7 # someone's '''comment
+print '''
+        there
+        '''
+# someone else's comment
+"""
+
+
+    def test_quotes_with_pound(self):
+        text = '''
+        if True:
+            """#"""
+        elif False:
+            "bar"
+'''
+        assert adjust_whitespace(text) == \
+'''
+if True:
+    """#"""
+elif False:
+    "bar"
+'''
+
+    def test_quotes(self):
+        text = """
+        print ''' aslkjfnas kjdfn
+askdjfnaskfd fkasnf dknf sadkfjn asdkfjna sdakjn
+asdkfjnads kfajns '''
+        if x:
+            print y
+"""
+        assert adjust_whitespace(text) == \
+"""
+print ''' aslkjfnas kjdfn
+askdjfnaskfd fkasnf dknf sadkfjn asdkfjna sdakjn
+asdkfjnads kfajns '''
+if x:
+    print y
+"""
diff --git a/lib3/Mako-0.7.3/test/test_template.py b/lib3/Mako-0.7.3/test/test_template.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_template.py
@@ -0,0 +1,1242 @@
+# -*- coding: utf-8 -*-
+
+from mako.template import Template, ModuleTemplate
+from mako.lookup import TemplateLookup
+from mako.ext.preprocessors import convert_comments
+from mako import exceptions, util, runtime
+import re
+import os
+from .util import flatten_result, result_lines
+import codecs
+from test import TemplateTest, eq_, template_base, module_base, \
+    requires_python_26_or_greater, assert_raises, assert_raises_message, \
+    requires_python_2
+
+class EncodingTest(TemplateTest):
+    def test_escapes_html_tags(self):
+        from mako.exceptions import html_error_template
+
+        x = Template("""
+        X:
+        <% raise Exception('<span style="color:red">Foobar</span>') %>
+        """)
+
+        try:
+            x.render()
+        except:
+            # <h3>Exception: <span style="color:red">Foobar</span></h3>
+            markup = html_error_template().render(full=False, css=False)
+            if util.py3k:
+                assert '<span style="color:red">Foobar</span></h3>'\
+                            .encode('ascii') not in markup
+                assert '<span style="color:red"'\
+                            '>Foobar</span>'\
+                            .encode('ascii') in markup
+            else:
+                assert '<span style="color:red">Foobar</span></h3>' \
+                            not in markup
+                assert '<span style="color:red"'\
+                            '>Foobar</span>' in markup
+
+    def test_unicode(self):
+        self._do_memory_test(
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+    def test_encoding_doesnt_conflict(self):
+        self._do_memory_test(
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            output_encoding='utf-8'
+        )
+
+    def test_unicode_arg(self):
+        val = """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        self._do_memory_test(
+            "${val}",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            template_args={'val':val}
+        )
+
+    def test_unicode_file(self):
+        self._do_file_test(
+            "unicode.html",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+    def test_unicode_file_code(self):
+        self._do_file_test(
+            'unicode_code.html',
+            """hi, drôle de petite voix m’a réveillé.""",
+            filters=flatten_result
+        )
+
+    def test_unicode_file_lookup(self):
+        lookup = TemplateLookup(
+                    directories=[template_base],
+                    output_encoding='utf-8',
+                    default_filters=['decode.utf8'])
+        if util.py3k:
+            template = lookup.get_template('/chs_unicode_py3k.html')
+        else:
+            template = lookup.get_template('/chs_unicode.html')
+        eq_(
+            flatten_result(template.render_unicode(name='毛泽东')),
+            '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京.'
+        )
+
+    def test_unicode_bom(self):
+        self._do_file_test(
+            'bom.html',
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+        self._do_file_test(
+            'bommagic.html',
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+        self.assertRaises(
+            exceptions.CompileException,
+            Template, filename=self._file_path('badbom.html'),
+            module_directory=module_base
+        )
+
+    def test_unicode_memory(self):
+        val = """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        self._do_memory_test(
+            ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'),
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+    def test_unicode_text(self):
+        val = """<%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »</%text>"""
+        self._do_memory_test(
+            ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'),
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+    def test_unicode_text_ccall(self):
+        val = """
+        <%def name="foo()">
+            ${capture(caller.body)}
+        </%def>
+        <%call expr="foo()">
+        <%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »</%text>
+        </%call>"""
+        self._do_memory_test(
+            ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'),
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            filters=flatten_result
+        )
+
+    def test_unicode_literal_in_expr(self):
+        if util.py3k:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                ${"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
+                """.encode('utf-8'),
+                """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+                filters = lambda s:s.strip()
+            )
+        else:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                ${u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
+                """.encode('utf-8'),
+                """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+                filters = lambda s:s.strip()
+            )
+
+    def test_unicode_literal_in_expr_file(self):
+        self._do_file_test(
+            'unicode_expr.html',
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            lambda t:t.strip()
+        )
+
+    def test_unicode_literal_in_code(self):
+        if util.py3k:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%
+                    context.write("Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »")
+                %>
+                """.encode('utf-8'),
+                """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+                filters=lambda s:s.strip()
+            )
+        else:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%
+                    context.write(u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »")
+                %>
+                """.encode('utf-8'),
+                """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+                filters=lambda s:s.strip()
+            )
+
+    def test_unicode_literal_in_controlline(self):
+        if util.py3k:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%
+                    x = "drôle de petite voix m’a réveillé."
+                %>
+                % if x=="drôle de petite voix m’a réveillé.":
+                    hi, ${x}
+                % endif
+                """.encode('utf-8'),
+                """hi, drôle de petite voix m’a réveillé.""",
+                filters=lambda s:s.strip(),
+            )
+        else:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%
+                    x = u"drôle de petite voix m’a réveillé."
+                %>
+                % if x==u"drôle de petite voix m’a réveillé.":
+                    hi, ${x}
+                % endif
+                """.encode('utf-8'),
+                """hi, drôle de petite voix m’a réveillé.""",
+                filters=lambda s:s.strip(),
+            )
+
+    def test_unicode_literal_in_tag(self):
+        self._do_file_test(
+            "unicode_arguments.html",
+            [
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+            ],
+            filters=result_lines
+        )
+
+        self._do_memory_test(
+            open(self._file_path("unicode_arguments.html"), 'rb').read(),
+            [
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+            ],
+            filters=result_lines
+        )
+
+    def test_unicode_literal_in_def(self):
+        if util.py3k:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%def name="bello(foo, bar)">
+                Foo: ${ foo }
+                Bar: ${ bar }
+                </%def>
+                <%call expr="bello(foo='árvíztűrő tükörfúrógép', bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+                </%call>""".encode('utf-8'),
+                """Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP""",
+                filters=flatten_result
+            )
+
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%def name="hello(foo='árvíztűrő tükörfúrógép', bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+                Foo: ${ foo }
+                Bar: ${ bar }
+                </%def>
+                ${ hello() }""".encode('utf-8'),
+                """Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP""",
+                filters=flatten_result
+            )
+        else:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%def name="bello(foo, bar)">
+                Foo: ${ foo }
+                Bar: ${ bar }
+                </%def>
+                <%call expr="bello(foo=u'árvíztűrő tükörfúrógép', bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+                </%call>""".encode('utf-8'),
+                """Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP""",
+                filters=flatten_result
+            )
+
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%def name="hello(foo=u'árvíztűrő tükörfúrógép', bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+                Foo: ${ foo }
+                Bar: ${ bar }
+                </%def>
+                ${ hello() }""".encode('utf-8'),
+                """Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP""",
+                filters=flatten_result
+            )
+
+    def test_input_encoding(self):
+        """test the 'input_encoding' flag on Template, and that unicode
+            objects arent double-decoded"""
+
+        if util.py3k:
+            self._do_memory_test(
+                "hello ${f('śląsk')}",
+                "hello śląsk",
+                input_encoding='utf-8',
+                template_args={'f':lambda x:x}
+            )
+
+            self._do_memory_test(
+                "## -*- coding: utf-8 -*-\nhello ${f('śląsk')}",
+                "hello śląsk",
+                template_args={'f':lambda x:x}
+            )
+        else:
+            self._do_memory_test(
+                "hello ${f(u'śląsk')}",
+                "hello śląsk",
+                input_encoding='utf-8',
+                template_args={'f':lambda x:x}
+            )
+
+            self._do_memory_test(
+                "## -*- coding: utf-8 -*-\nhello ${f(u'śląsk')}",
+                "hello śląsk",
+                template_args={'f':lambda x:x}
+            )
+
+    def test_raw_strings(self):
+        """test that raw strings go straight thru with default_filters turned off,
+        bytestring_passthrough enabled.
+
+        """
+
+        self._do_memory_test(
+            "## -*- coding: utf-8 -*-\nhello ${x}",
+            "hello śląsk",
+            default_filters=[],
+            template_args={'x':'śląsk'},
+            unicode_=False,
+            bytestring_passthrough=True,
+            output_encoding=None #'ascii'
+        )
+
+        # now, the way you *should* be doing it....
+        self._do_memory_test(
+            "## -*- coding: utf-8 -*-\nhello ${x}",
+            "hello śląsk",
+            template_args={'x':'śląsk'}
+        )
+
+    def test_encoding(self):
+        self._do_memory_test(
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""".encode('utf-8'),
+            output_encoding='utf-8',
+            unicode_=False
+        )
+
+    def test_encoding_errors(self):
+        self._do_memory_test(
+            """KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: Комит́ет Госуд́арственной Безоп́асности (help·info); Komitet Gosudarstvennoy Bezopasnosti)""",
+            """KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: Комит́ет Госуд́арственной Безоп́асности (help·info); Komitet Gosudarstvennoy Bezopasnosti)""".encode('iso-8859-1', 'replace'),
+            output_encoding='iso-8859-1', encoding_errors='replace',
+            unicode_=False
+        )
+
+    def test_read_unicode(self):
+        lookup = TemplateLookup(directories=[template_base],
+                                filesystem_checks=True, output_encoding='utf-8')
+        if util.py3k:
+            template = lookup.get_template('/read_unicode_py3k.html')
+        else:
+            template = lookup.get_template('/read_unicode.html')
+        # TODO: I've no idea what encoding this file is, Python 3.1.2
+        # won't read the file even with open(...encoding='utf-8') unless
+        # errors is specified.   or if there's some quirk in 3.1.2
+        # since I'm pretty sure this test worked with py3k when I wrote it.
+        data = template.render(path=self._file_path('internationalization.html'))
+
+    @requires_python_2
+    def test_bytestring_passthru(self):
+        self._do_file_test(
+            'chs_utf8.html',
+            '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.',
+            default_filters=[],
+            disable_unicode=True,
+            output_encoding=None,
+            template_args={'name':'毛泽东'},
+            filters=flatten_result,
+            unicode_=False
+        )
+
+        self._do_file_test(
+            'chs_utf8.html',
+            '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.',
+            disable_unicode=True,
+            output_encoding=None,
+            template_args={'name':'毛泽东'},
+            filters=flatten_result,
+            unicode_=False
+        )
+
+        template = self._file_template('chs_utf8.html',
+                    output_encoding=None,
+                    disable_unicode=True)
+        self.assertRaises(UnicodeDecodeError, template.render_unicode, name='毛泽东')
+
+        template = Template(
+            "${'Alors vous imaginez ma surprise, au lever"
+            " du jour, quand une drôle de petite voix m’a "
+            "réveillé. Elle disait: « S’il vous plaît… "
+            "dessine-moi un mouton! »'}",
+            output_encoding=None,
+            disable_unicode=True, input_encoding='utf-8')
+        assert template.render() == "Alors vous imaginez ma surprise, "\
+                "au lever du jour, quand une drôle de petite "\
+                "voix m’a réveillé. Elle disait: « S’il vous "\
+                "plaît… dessine-moi un mouton! »"
+        template = Template(
+                "${'Alors vous imaginez ma surprise, au "
+                "lever du jour, quand une drôle de petite "
+                "voix m’a réveillé. Elle disait: « S’il "
+                "vous plaît… dessine-moi un mouton! »'}",
+                input_encoding='utf8', output_encoding='utf8',
+                disable_unicode=False, default_filters=[])
+        # raises because expression contains an encoded bytestring which cannot be decoded
+        self.assertRaises(UnicodeDecodeError, template.render)
+
+
+class PageArgsTest(TemplateTest):
+    def test_basic(self):
+        template = Template("""
+            <%page args="x, y, z=7"/>
+
+            this is page, ${x}, ${y}, ${z}
+""")
+
+        assert flatten_result(template.render(x=5, y=10)) == "this is page, 5, 10, 7"
+        assert flatten_result(template.render(x=5, y=10, z=32)) == "this is page, 5, 10, 32"
+        try:
+            template.render(y=10)
+            assert False
+        except TypeError as e:
+            assert True
+
+    def test_inherits(self):
+        lookup = TemplateLookup()
+        lookup.put_string("base.tmpl",
+        """
+        <%page args="bar" />
+        ${bar}
+        ${pageargs['foo']}
+        ${self.body(**pageargs)}
+        """
+        )
+        lookup.put_string("index.tmpl", """
+        <%inherit file="base.tmpl" />
+        <%page args="variable" />
+        ${variable}
+        """)
+
+        self._do_test(
+            lookup.get_template("index.tmpl"),
+            "bar foo var",
+            filters=flatten_result,
+            template_args={'variable':'var', 'bar':'bar', 'foo':'foo'}
+
+        )
+
+    def test_includes(self):
+        lookup = TemplateLookup()
+        lookup.put_string("incl1.tmpl",
+        """
+        <%page args="bar" />
+        ${bar}
+        ${pageargs['foo']}
+        """
+        )
+        lookup.put_string("incl2.tmpl",
+        """
+        ${pageargs}
+        """
+        )
+        lookup.put_string("index.tmpl", """
+        <%include file="incl1.tmpl" args="**pageargs"/>
+        <%page args="variable" />
+        ${variable}
+        <%include file="incl2.tmpl" />
+        """)
+
+        self._do_test(
+            lookup.get_template("index.tmpl"),
+            "bar foo var {}",
+            filters=flatten_result,
+            template_args={'variable':'var', 'bar':'bar', 'foo':'foo'}
+
+        )
+
+    def test_context_small(self):
+        ctx = runtime.Context([].append, x=5, y=4)
+        eq_(sorted(ctx.keys()), ['caller', 'capture', 'x', 'y'])
+
+    def test_with_context(self):
+        template = Template("""
+            <%page args="x, y, z=7"/>
+
+            this is page, ${x}, ${y}, ${z}, ${w}
+""")
+        #print template.code
+        assert flatten_result(template.render(x=5, y=10, w=17)) == "this is page, 5, 10, 7, 17"
+
+    def test_overrides_builtins(self):
+        template = Template("""
+            <%page args="id"/>
+
+            this is page, id is ${id}
+        """)
+
+        assert flatten_result(template.render(id="im the id")) == "this is page, id is im the id"
+
+    def test_canuse_builtin_names(self):
+        template = Template("""
+            exception: ${Exception}
+            id: ${id}
+        """)
+        assert flatten_result(template.render(id='some id', Exception='some exception')) == "exception: some exception id: some id"
+
+    def test_builtin_names_dont_clobber_defaults_in_includes(self):
+        lookup = TemplateLookup()
+        lookup.put_string("test.mako",
+        """
+        <%include file="test1.mako"/>
+
+        """)
+
+        lookup.put_string("test1.mako", """
+        <%page args="id='foo'"/>
+
+        ${id}
+        """)
+
+        for template in ("test.mako", "test1.mako"):
+            assert flatten_result(lookup.get_template(template).render()) == "foo"
+            assert flatten_result(lookup.get_template(template).render(id=5)) == "5"
+            assert flatten_result(lookup.get_template(template).render(id=id)) == "<built-in function id>"
+
+    def test_dict_locals(self):
+        template = Template("""
+            <%
+                dict = "this is dict"
+                locals = "this is locals"
+            %>
+            dict: ${dict}
+            locals: ${locals}
+        """)
+        assert flatten_result(template.render()) == "dict: this is dict locals: this is locals"
+
+class IncludeTest(TemplateTest):
+    def test_basic(self):
+        lookup = TemplateLookup()
+        lookup.put_string("a", """
+            this is a
+            <%include file="b" args="a=3,b=4,c=5"/>
+        """)
+        lookup.put_string("b", """
+            <%page args="a,b,c"/>
+            this is b.  ${a}, ${b}, ${c}
+        """)
+        assert flatten_result(lookup.get_template("a").render()) == "this is a this is b. 3, 4, 5"
+
+    def test_localargs(self):
+        lookup = TemplateLookup()
+        lookup.put_string("a", """
+            this is a
+            <%include file="b" args="a=a,b=b,c=5"/>
+        """)
+        lookup.put_string("b", """
+            <%page args="a,b,c"/>
+            this is b.  ${a}, ${b}, ${c}
+        """)
+        assert flatten_result(lookup.get_template("a").render(a=7,b=8)) == "this is a this is b. 7, 8, 5"
+
+    def test_viakwargs(self):
+        lookup = TemplateLookup()
+        lookup.put_string("a", """
+            this is a
+            <%include file="b" args="c=5, **context.kwargs"/>
+        """)
+        lookup.put_string("b", """
+            <%page args="a,b,c"/>
+            this is b.  ${a}, ${b}, ${c}
+        """)
+        #print lookup.get_template("a").code
+        assert flatten_result(lookup.get_template("a").render(a=7,b=8)) == "this is a this is b. 7, 8, 5"
+
+    def test_include_withargs(self):
+        lookup = TemplateLookup()
+        lookup.put_string("a", """
+            this is a
+            <%include file="${i}" args="c=5, **context.kwargs"/>
+        """)
+        lookup.put_string("b", """
+            <%page args="a,b,c"/>
+            this is b.  ${a}, ${b}, ${c}
+        """)
+        assert flatten_result(lookup.get_template("a").render(a=7,b=8,i='b')) == "this is a this is b. 7, 8, 5"
+
+    def test_within_ccall(self):
+        lookup = TemplateLookup()
+        lookup.put_string("a", """this is a""")
+        lookup.put_string("b", """
+        <%def name="bar()">
+            bar: ${caller.body()}
+            <%include file="a"/>
+        </%def>
+        """)
+        lookup.put_string("c", """
+        <%namespace name="b" file="b"/>
+        <%b:bar>
+            calling bar
+        </%b:bar>
+        """)
+        assert flatten_result(lookup.get_template("c").render()) == "bar: calling bar this is a"
+
+class UndefinedVarsTest(TemplateTest):
+    def test_undefined(self):
+        t = Template("""
+            % if x is UNDEFINED:
+                undefined
+            % else:
+                x: ${x}
+            % endif
+        """)
+
+        assert result_lines(t.render(x=12)) == ["x: 12"]
+        assert result_lines(t.render(y=12)) == ["undefined"]
+
+    def test_strict(self):
+        t = Template("""
+            % if x is UNDEFINED:
+                undefined
+            % else:
+                x: ${x}
+            % endif
+        """, strict_undefined=True)
+
+        assert result_lines(t.render(x=12)) == ['x: 12']
+
+        assert_raises(
+            NameError,
+            t.render, y=12
+        )
+
+        l = TemplateLookup(strict_undefined=True)
+        l.put_string("a", "some template")
+        l.put_string("b", """
+            <%namespace name='a' file='a' import='*'/>
+            % if x is UNDEFINED:
+                undefined
+            % else:
+                x: ${x}
+            % endif
+        """)
+
+        assert result_lines(t.render(x=12)) == ['x: 12']
+
+        assert_raises(
+            NameError,
+            t.render, y=12
+        )
+
+    def test_expression_declared(self):
+        t = Template("""
+            ${",".join([t for t in ("a", "b", "c")])}
+        """, strict_undefined=True)
+
+        eq_(result_lines(t.render()), ['a,b,c'])
+
+        t = Template("""
+            <%self:foo value="${[(val, n) for val, n in [(1, 2)]]}"/>
+
+            <%def name="foo(value)">
+                ${value}
+            </%def>
+
+        """, strict_undefined=True)
+
+        eq_(result_lines(t.render()), ['[(1, 2)]'])
+
+        t = Template("""
+            <%call expr="foo(value=[(val, n) for val, n in [(1, 2)]])" />
+
+            <%def name="foo(value)">
+                ${value}
+            </%def>
+
+        """, strict_undefined=True)
+
+        eq_(result_lines(t.render()), ['[(1, 2)]'])
+
+        l = TemplateLookup(strict_undefined=True)
+        l.put_string("i", "hi, ${pageargs['y']}")
+        l.put_string("t", """
+            <%include file="i" args="y=[x for x in range(3)]" />
+        """)
+        eq_(
+            result_lines(l.get_template("t").render()), ['hi, [0, 1, 2]']
+        )
+
+        l.put_string('q', """
+            <%namespace name="i" file="${(str([x for x in range(3)][2]) + 'i')[-1]}" />
+            ${i.body(y='x')}
+        """)
+        eq_(
+            result_lines(l.get_template("q").render()), ['hi, x']
+        )
+
+        t = Template("""
+            <%
+                y = lambda q: str(q)
+            %>
+            ${y('hi')}
+        """, strict_undefined=True)
+        eq_(
+            result_lines(t.render()), ["hi"]
+        )
+
+    def test_list_comprehensions_plus_undeclared_nonstrict(self):
+        # traditional behavior.  variable inside a list comprehension
+        # is treated as an "undefined", so is pulled from the context.
+        t = Template("""
+            t is: ${t}
+
+            ${",".join([t for t in ("a", "b", "c")])}
+        """)
+
+        eq_(
+            result_lines(t.render(t="T")),
+            ['t is: T', 'a,b,c']
+        )
+
+    def test_traditional_assignment_plus_undeclared(self):
+        t = Template("""
+            t is: ${t}
+
+            <%
+                t = 12
+            %>
+        """)
+        assert_raises(
+            UnboundLocalError,
+            t.render, t="T"
+        )
+
+    def test_list_comprehensions_plus_undeclared_strict(self):
+        # with strict, a list comprehension now behaves
+        # like the undeclared case above.
+        t = Template("""
+            t is: ${t}
+
+            ${",".join([t for t in ("a", "b", "c")])}
+        """, strict_undefined=True)
+
+        eq_(
+            result_lines(t.render(t="T")),
+            ['t is: T', 'a,b,c']
+        )
+
+class ReservedNameTest(TemplateTest):
+    def test_names_on_context(self):
+        for name in ('context', 'loop', 'UNDEFINED'):
+            assert_raises_message(
+                exceptions.NameConflictError,
+                r"Reserved words passed to render\(\): %s" % name,
+                Template("x").render, **{name:'foo'}
+            )
+
+    def test_names_in_template(self):
+        for name in ('context', 'loop', 'UNDEFINED'):
+            assert_raises_message(
+                exceptions.NameConflictError,
+                r"Reserved words declared in template: %s" % name,
+                Template, "<%% %s = 5 %%>" % name
+            )
+
+    def test_exclude_loop_context(self):
+        self._do_memory_test(
+            "loop is ${loop}",
+            "loop is 5",
+            template_args=dict(loop=5),
+            enable_loop=False
+        )
+
+    def test_exclude_loop_template(self):
+        self._do_memory_test(
+            "<% loop = 12 %>loop is ${loop}",
+            "loop is 12",
+            enable_loop=False
+        )
+
+class ControlTest(TemplateTest):
+    def test_control(self):
+        t = Template("""
+    ## this is a template.
+    % for x in y:
+    %   if 'test' in x:
+        yes x has test
+    %   else:
+        no x does not have test
+    %endif
+    %endfor
+""")
+        assert result_lines(t.render(y=[{'test':'one'}, {'foo':'bar'}, {'foo':'bar', 'test':'two'}])) == [
+            "yes x has test",
+            "no x does not have test",
+            "yes x has test"
+        ]
+
+    def test_blank_control_1(self):
+        self._do_memory_test(
+            """
+            % if True:
+            % endif
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_blank_control_2(self):
+        self._do_memory_test(
+            """
+            % if True:
+            % elif True:
+            % endif
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_blank_control_3(self):
+        self._do_memory_test(
+            """
+            % if True:
+            % else:
+            % endif
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_blank_control_4(self):
+        self._do_memory_test(
+            """
+            % if True:
+            % elif True:
+            % else:
+            % endif
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_blank_control_5(self):
+        self._do_memory_test(
+            """
+            % for x in range(10):
+            % endfor
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_blank_control_6(self):
+        self._do_memory_test(
+            """
+            % while False:
+            % endwhile
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_blank_control_7(self):
+        self._do_memory_test(
+            """
+            % try:
+            % except:
+            % endtry
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    @requires_python_26_or_greater
+    def test_blank_control_8(self):
+        self._do_memory_test(
+            """
+            % with open('x', 'w') as fp:
+            % endwith
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_commented_blank_control_1(self):
+        self._do_memory_test(
+            """
+            % if True:
+            ## comment
+            % endif
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_commented_blank_control_2(self):
+        self._do_memory_test(
+            """
+            % if True:
+            ## comment
+            % elif True:
+            ## comment
+            % endif
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_commented_blank_control_3(self):
+        self._do_memory_test(
+            """
+            % if True:
+            ## comment
+            % else:
+            ## comment
+            % endif
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_commented_blank_control_4(self):
+        self._do_memory_test(
+            """
+            % if True:
+            ## comment
+            % elif True:
+            ## comment
+            % else:
+            ## comment
+            % endif
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_commented_blank_control_5(self):
+        self._do_memory_test(
+            """
+            % for x in range(10):
+            ## comment
+            % endfor
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_commented_blank_control_6(self):
+        self._do_memory_test(
+            """
+            % while False:
+            ## comment
+            % endwhile
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_commented_blank_control_7(self):
+        self._do_memory_test(
+            """
+            % try:
+            ## comment
+            % except:
+            ## comment
+            % endtry
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    @requires_python_26_or_greater
+    def test_commented_blank_control_8(self):
+        self._do_memory_test(
+            """
+            % with open('x', 'w') as fp:
+            ## comment
+            % endwith
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+
+    def test_multiline_control(self):
+        t = Template("""
+    % for x in \\
+        [y for y in [1,2,3]]:
+        ${x}
+    % endfor
+""")
+        #print t.code
+        assert flatten_result(t.render()) == "1 2 3"
+
+class GlobalsTest(TemplateTest):
+    def test_globals(self):
+        self._do_memory_test(
+            """
+                <%!
+                    y = "hi"
+                %>
+            y is ${y}
+            """,
+            "y is hi",
+            filters=lambda t:t.strip()
+        )
+
+class RichTracebackTest(TemplateTest):
+
+    def _do_test_traceback(self, utf8, memory, syntax):
+        if memory:
+            if syntax:
+                source = '## coding: utf-8\n<% print "m’a réveillé. '\
+                        'Elle disait: « S’il vous plaît… dessine-moi un mouton! » %>'
+            else:
+                source = '## coding: utf-8\n<% print u"m’a réveillé. '\
+                        'Elle disait: « S’il vous plaît… dessine-moi un mouton! »" + str(5/0) %>'
+            if utf8:
+                source = source.encode('utf-8')
+            else:
+                source = source
+            templateargs = {'text':source}
+        else:
+            if syntax:
+                filename = 'unicode_syntax_error.html'
+            else:
+                filename = 'unicode_runtime_error.html'
+            source = open(self._file_path(filename), 'rb').read()
+            if not utf8:
+                source = source.decode('utf-8')
+            templateargs = {'filename':self._file_path(filename)}
+        try:
+            template = Template(**templateargs)
+            if not syntax:
+                template.render_unicode()
+            assert False
+        except Exception as e:
+            tback = exceptions.RichTraceback()
+            if utf8:
+                assert tback.source == source.decode('utf-8')
+            else:
+                assert tback.source == source
+
+for utf8 in (True, False):
+    for memory in (True, False):
+        for syntax in (True, False):
+            def _do_test(self):
+                self._do_test_traceback(utf8, memory, syntax)
+            name = 'test_%s_%s_%s' % (utf8 and 'utf8' or 'unicode',
+                                        memory and 'memory' or 'file',
+                                        syntax and 'syntax' or 'runtime')
+            _do_test.__name__ = name
+            setattr(RichTracebackTest, name, _do_test)
+            del _do_test
+
+class ModuleDirTest(TemplateTest):
+    def tearDown(self):
+        import shutil
+        shutil.rmtree(module_base, True)
+
+    def test_basic(self):
+        t = self._file_template("modtest.html")
+        t2 = self._file_template('subdir/modtest.html')
+
+        eq_(
+            t.module.__file__,
+            os.path.join(module_base, 'modtest.html.py')
+        )
+        eq_(
+            t2.module.__file__,
+            os.path.join(module_base, 'subdir', 'modtest.html.py')
+        )
+
+    def test_callable(self):
+        def get_modname(filename, uri):
+            return os.path.join(
+                        module_base,
+                        os.path.dirname(uri)[1:],
+                        'foo',
+                        os.path.basename(filename) + ".py")
+
+        lookup = TemplateLookup(template_base, modulename_callable=get_modname)
+        t = lookup.get_template('/modtest.html')
+        t2 = lookup.get_template('/subdir/modtest.html')
+        eq_(
+            t.module.__file__,
+            os.path.join(module_base, 'foo', 'modtest.html.py')
+        )
+        eq_(
+            t2.module.__file__,
+            os.path.join(module_base, 'subdir', 'foo', 'modtest.html.py')
+        )
+
+    def test_custom_writer(self):
+        canary = []
+        def write_module(source, outputpath):
+            f = open(outputpath, 'wb')
+            canary.append(outputpath)
+            f.write(source)
+            f.close()
+        lookup = TemplateLookup(template_base, module_writer=write_module,
+                                            module_directory=module_base)
+        t = lookup.get_template('/modtest.html')
+        t2 = lookup.get_template('/subdir/modtest.html')
+        eq_(
+            canary,
+            [os.path.join(module_base, "modtest.html.py"),
+            os.path.join(module_base, "subdir/modtest.html.py")]
+        )
+
+class FilenameToURITest(TemplateTest):
+    def test_windows_paths(self):
+        """test that windows filenames are handled appropriately by Template."""
+
+        current_path = os.path
+        import ntpath
+        os.path = ntpath
+        try:
+            class NoCompileTemplate(Template):
+                def _compile_from_file(self, path, filename):
+                    self.path = path
+                    return Template("foo bar").module
+
+            t1 = NoCompileTemplate(
+                                    filename="c:\\foo\\template.html",
+                                    module_directory="c:\\modules\\")
+
+            eq_(t1.uri, "/foo/template.html")
+            eq_(t1.path, "c:\\modules\\foo\\template.html.py")
+
+            t1 = NoCompileTemplate(
+                                    filename="c:\\path\\to\\templates\\template.html",
+                                    uri = "/bar/template.html",
+                                    module_directory="c:\\modules\\")
+
+            eq_(t1.uri, "/bar/template.html")
+            eq_(t1.path, "c:\\modules\\bar\\template.html.py")
+
+        finally:
+            os.path = current_path
+
+    def test_posix_paths(self):
+        """test that posixs filenames are handled appropriately by Template."""
+
+        current_path = os.path
+        import posixpath
+        os.path = posixpath
+        try:
+            class NoCompileTemplate(Template):
+                def _compile_from_file(self, path, filename):
+                    self.path = path
+                    return Template("foo bar").module
+
+            t1 = NoCompileTemplate(
+                                    filename="/var/www/htdocs/includes/template.html",
+                                    module_directory="/var/lib/modules")
+
+            eq_(t1.uri, "/var/www/htdocs/includes/template.html")
+            eq_(t1.path, "/var/lib/modules/var/www/htdocs/includes/template.html.py")
+
+            t1 = NoCompileTemplate(
+                                    filename="/var/www/htdocs/includes/template.html",
+                                    uri = "/bar/template.html",
+                                    module_directory="/var/lib/modules")
+
+            eq_(t1.uri, "/bar/template.html")
+            eq_(t1.path, "/var/lib/modules/bar/template.html.py")
+
+        finally:
+            os.path = current_path
+
+    def test_dont_accept_relative_outside_of_root(self):
+        assert_raises_message(
+            exceptions.TemplateLookupException,
+            "Template uri \"../../foo.html\" is invalid - it "
+            "cannot be relative outside of the root path",
+            Template, "test", uri="../../foo.html",
+        )
+
+        assert_raises_message(
+            exceptions.TemplateLookupException,
+            "Template uri \"/../../foo.html\" is invalid - it "
+            "cannot be relative outside of the root path",
+            Template, "test", uri="/../../foo.html",
+        )
+
+        # normalizes in the root is OK
+        t = Template("test", uri="foo/bar/../../foo.html")
+        eq_(t.uri, "foo/bar/../../foo.html")
+
+
+class ModuleTemplateTest(TemplateTest):
+    def test_module_roundtrip(self):
+        lookup = TemplateLookup()
+
+        template = Template("""
+        <%inherit file="base.html"/>
+
+        % for x in range(5):
+            ${x}
+        % endfor
+""", lookup=lookup)
+
+        base = Template("""
+        This is base.
+        ${self.body()}
+""", lookup=lookup)
+
+        lookup.put_template("base.html", base)
+        lookup.put_template("template.html", template)
+
+        assert result_lines(template.render()) == [
+            "This is base.", "0", "1", "2", "3", "4"
+        ]
+
+        lookup = TemplateLookup()
+        template = ModuleTemplate(template.module, lookup=lookup)
+        base = ModuleTemplate(base.module, lookup=lookup)
+
+        lookup.put_template("base.html", base)
+        lookup.put_template("template.html", template)
+
+        assert result_lines(template.render()) == [
+            "This is base.", "0", "1", "2", "3", "4"
+        ]
+
+
+class PreprocessTest(TemplateTest):
+    def test_old_comments(self):
+        t = Template("""
+        im a template
+# old style comment
+    # more old style comment
+
+    ## new style comment
+    - # not a comment
+    - ## not a comment
+""", preprocessor=convert_comments)
+
+        assert flatten_result(t.render()) == "im a template - # not a comment - ## not a comment"
diff --git a/lib3/Mako-0.7.3/test/test_tgplugin.py b/lib3/Mako-0.7.3/test/test_tgplugin.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_tgplugin.py
@@ -0,0 +1,42 @@
+import unittest
+
+from mako.ext.turbogears import TGPlugin
+from .util import flatten_result, result_lines
+from test import TemplateTest, template_base
+
+tl = TGPlugin(options=dict(directories=[template_base]), extension='html')
+
+class TestTGPlugin(TemplateTest):
+    def test_basic(self):
+        t = tl.load_template('/index.html')
+        assert result_lines(t.render()) == [
+            "this is index"
+        ]
+    def test_subdir(self):
+        t = tl.load_template('/subdir/index.html')
+        assert result_lines(t.render()) == [
+            "this is sub index",
+            "this is include 2"
+
+        ]
+
+        assert tl.load_template('/subdir/index.html').module_id == '_subdir_index_html'
+
+    def test_basic_dot(self):
+        t = tl.load_template('index')
+        assert result_lines(t.render()) == [
+            "this is index"
+        ]
+    def test_subdir_dot(self):
+        t = tl.load_template('subdir.index')
+        assert result_lines(t.render()) == [
+            "this is sub index",
+            "this is include 2"
+
+        ]
+
+        assert tl.load_template('subdir.index').module_id == '_subdir_index_html'
+ 
+    def test_string(self):
+        t = tl.load_template('foo', "hello world")
+        assert t.render() == "hello world"
diff --git a/lib3/Mako-0.7.3/test/test_util.py b/lib3/Mako-0.7.3/test/test_util.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/test_util.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+import os
+import unittest
+from mako import util, exceptions
+from test import eq_, skip_if, assert_raises_message
+
+class UtilTest(unittest.TestCase):
+    def test_fast_buffer_write(self):
+        buf = util.FastEncodingBuffer()
+        buf.write("string a ")
+        buf.write("string b")
+        eq_(buf.getvalue(), "string a string b")
+
+    def test_fast_buffer_truncate(self):
+        buf = util.FastEncodingBuffer()
+        buf.write("string a ")
+        buf.write("string b")
+        buf.truncate()
+        buf.write("string c ")
+        buf.write("string d")
+        eq_(buf.getvalue(), "string c string d")
+
+    def test_fast_buffer_encoded(self):
+        s = "drôl m’a rée « S’il"
+        buf = util.FastEncodingBuffer(encoding='utf-8')
+        buf.write(s[0:10])
+        buf.write(s[10:])
+        q = buf.getvalue()
+        eq_(buf.getvalue(), s.encode('utf-8'))
+
+    def test_read_file(self):
+        fn = os.path.join(os.path.dirname(__file__), 'test_util.py')
+        data = util.read_file(fn, 'rb')
+        self.failUnless('test_util' in str(data)) # str() for py3k
+
+    @skip_if(lambda: util.pypy, "Pypy does this differently")
+    def test_load_module(self):
+        fn = os.path.join(os.path.dirname(__file__), 'test_util.py')
+        module = util.load_module('mako.template', fn)
+        import mako.template
+        self.assertEqual(module, mako.template)
+
+    def test_load_plugin_failure(self):
+        loader = util.PluginLoader("fakegroup")
+        assert_raises_message(
+            exceptions.RuntimeException,
+            "Can't load plugin fakegroup fake",
+            loader.load, "fake"
+        )
diff --git a/lib3/Mako-0.7.3/test/util.py b/lib3/Mako-0.7.3/test/util.py
new file mode 100644
--- /dev/null
+++ b/lib3/Mako-0.7.3/test/util.py
@@ -0,0 +1,7 @@
+import re
+
+def flatten_result(result):
+    return re.sub(r'[\s\r\n]+', ' ', result).strip()
+
+def result_lines(result):
+    return [x.strip() for x in re.split(r'\r?\n', re.sub(r' +', ' ', result)) if x.strip() != '']
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/.hgignore b/lib3/mako-0.3.6/.hgignore
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/.hgignore
@@ -0,0 +1,7 @@
+syntax:regexp
+^build/
+^doc/build/output
+.pyc$
+.orig$
+Mako.egg-info
+easy-install.pth
diff --git a/lib3/mako-0.3.6/CHANGES b/lib3/mako-0.3.6/CHANGES
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/CHANGES
@@ -0,0 +1,590 @@
+0.3.6
+- Documentation is on Sphinx.
+  [ticket:126]
+
+- Beaker is now part of "extras" in
+  setup.py instead of "install_requires".
+  This to produce a lighter weight install
+  for those who don't use the caching
+  as well as to conform to Pyramid 
+  deployment practices.  [ticket:154]
+
+- The Beaker import (or attempt thereof)
+  is delayed until actually needed; 
+  this to remove the performance penalty 
+  from startup, particularly for 
+  "single execution" environments
+  such as shell scripts. [ticket:153]
+
+- Patch to lexer to not generate an empty
+  '' write in the case of backslash-ended
+  lines.  [ticket:155]
+    
+- Fixed missing **extra collection in 
+  setup.py which prevented setup.py
+  from running 2to3 on install.
+  [ticket:148]
+  
+- New flag on Template, TemplateLookup - 
+  strict_undefined=True, will cause
+  variables not found in the context to 
+  raise a NameError immediately, instead of
+  defaulting to the UNDEFINED value.
+
+- The range of Python identifiers that
+  are considered "undefined", meaning they
+  are pulled from the context, has been 
+  trimmed back to not include variables 
+  declared inside of expressions (i.e. from
+  list comprehensions), as well as 
+  in the argument list of lambdas.  This
+  to better support the strict_undefined
+  feature.  The change should be 
+  fully backwards-compatible but involved
+  a little bit of tinkering in the AST code,
+  which hadn't really been touched for 
+  a couple of years, just FYI.
+  
+0.3.5
+- The <%namespace> tag allows expressions
+  for the `file` argument, i.e. with ${}.
+  The `context` variable, if needed,
+  must be referenced explicitly.
+  [ticket:141]
+
+- ${} expressions embedded in tags, 
+  such as <%foo:bar x="${...}">, now 
+  allow multiline Python expressions.
+  
+- Fixed previously non-covered regular 
+  expression, such that using a ${} expression 
+  inside of a tag element that doesn't allow 
+  them raises a CompileException instead of
+  silently failing.
+
+- Added a try/except around "import markupsafe".
+  This to support GAE which can't run markupsafe.
+  [ticket:151] No idea whatsoever if the 
+  install_requires in setup.py also breaks GAE, 
+  couldn't get an answer on this.
+  
+0.3.4
+- Now using MarkupSafe for HTML escaping,
+  i.e. in place of cgi.escape().  Faster
+  C-based implementation and also escapes
+  single quotes for additional security.
+  Supports the __html__ attribute for
+  the given expression as well.
+  
+  When using "disable_unicode" mode,
+  a pure Python HTML escaper function
+  is used which also quotes single quotes.
+  
+  Note that Pylons by default doesn't 
+  use Mako's filter - check your 
+  environment.py file.
+  
+- Fixed call to "unicode.strip" in 
+  exceptions.text_error_template which
+  is not Py3k compatible.  [ticket:137]
+  
+0.3.3
+- Added conditional to RichTraceback
+  such that if no traceback is passed
+  and sys.exc_info() has been reset,
+  the formatter just returns blank
+  for the "traceback" portion.
+  [ticket:135]
+  
+- Fixed sometimes incorrect usage of 
+  exc.__class__.__name__
+  in html/text error templates when using 
+  Python 2.4 [ticket:131]
+
+- Fixed broken @property decorator on 
+  template.last_modified
+
+- Fixed error formatting when a stacktrace
+  line contains no line number, as in when
+  inside an eval/exec-generated function.
+  [ticket:132]
+
+- When a .py is being created, the tempfile
+  where the source is stored temporarily is
+  now made in the same directory as that of
+  the .py file.  This ensures that the two
+  files share the same filesystem, thus 
+  avoiding cross-filesystem synchronization
+  issues.  Thanks to Charles Cazabon.
+  
+0.3.2
+- Calling a def from the top, via 
+  template.get_def(...).render() now checks the 
+  argument signature the same way as it did in 
+  0.2.5, so that TypeError is not raised.
+  reopen of [ticket:116]
+  
+  
+0.3.1
+- Fixed incorrect dir name in setup.py
+  [ticket:129]
+
+0.3
+- Python 2.3 support is dropped. [ticket:123]
+
+- Python 3 support is added ! See README.py3k
+  for installation and testing notes.
+  [ticket:119]
+  
+- Unit tests now run with nose.  [ticket:127]
+
+- Source code escaping has been simplified.
+  In particular, module source files are now 
+  generated with the Python "magic encoding 
+  comment", and source code is passed through 
+  mostly unescaped, except for that code which
+  is regenerated from parsed Python source.
+  This fixes usage of unicode in 
+  <%namespace:defname> tags.  [ticket:99]
+
+- RichTraceback(), html_error_template().render(),
+  text_error_template().render() now accept "error"
+  and "traceback" as optional arguments, and 
+  these are now actually used.  [ticket:122]
+  
+- The exception output generated when 
+  format_exceptions=True will now be as a Python
+  unicode if it occurred during render_unicode(),
+  or an encoded string if during render().
+
+- A percent sign can be emitted as the first
+  non-whitespace character on a line by escaping
+  it as in "%%". [ticket:112]
+ 
+- Template accepts empty control structure, i.e.
+  % if: %endif, etc. [ticket:94]
+
+- The <%page args> tag can now be used in a base 
+  inheriting template - the full set of render()
+  arguments are passed down through the inherits
+  chain.  Undeclared arguments go into **pageargs
+  as usual.  [ticket:116]
+
+- defs declared within a <%namespace> section, an
+  uncommon feature, have been improved.  The defs
+  no longer get doubly-rendered in the body() scope,
+  and now allow local variable assignment without
+  breakage.  [ticket:109]
+
+- Windows paths are handled correctly if a Template
+  is passed only an absolute filename (i.e. with c: 
+  drive etc.)  and no URI - the URI is converted
+  to a forward-slash path and module_directory
+  is treated as a windows path.  [ticket:128]
+
+- TemplateLookup raises TopLevelLookupException for
+  a given path that is a directory, not a filename,
+  instead of passing through to the template to 
+  generate IOError.  [ticket:73]
+  
+0.2.6
+
+- Fix mako function decorators to preserve the
+  original function's name in all cases. Patch
+  from Scott Torborg.
+
+- Support the <%namespacename:defname> syntax in
+  the babel extractor. [ticket:118]
+
+- Further fixes to unicode handling of .py files with the
+  html_error_template. [ticket:88]
+
+0.2.5
+- Added a "decorator" kw argument to <%def>,
+  allows custom decoration functions to wrap
+  rendering callables.  Mainly intended for
+  custom caching algorithms, not sure what
+  other uses there may be (but there may be).
+  Examples are in the "filtering" docs.
+
+- When Mako creates subdirectories in which
+  to store templates, it uses the more
+  permissive mode of 0775 instead of 0750,
+  helping out with certain multi-process 
+  scenarios. Note that the mode is always
+  subject to the restrictions of the existing
+  umask. [ticket:101]
+  
+- Fixed namespace.__getattr__() to raise 
+  AttributeError on attribute not found 
+  instead of RuntimeError.  [ticket:104]
+  
+- Added last_modified accessor to Template,
+  returns the time.time() when the module
+  was created. [ticket:97]
+
+- Fixed lexing support for whitespace
+  around '=' sign in defs. [ticket:102]
+
+- Removed errant "lower()" in the lexer which
+  was causing tags to compile with 
+  case-insensitive names, thus messing up
+  custom <%call> names. [ticket:108]
+
+- added "mako.__version__" attribute to
+  the base module.  [ticket:110]
+  
+0.2.4
+- Fixed compatibility with Jython 2.5b1.
+
+0.2.3
+- the <%namespacename:defname> syntax described at
+  http://techspot.zzzeek.org/?p=28 has now 
+  been added as a built in syntax, and is recommended
+  as a more modern syntax versus <%call expr="expression">.
+  The %call tag itself will always remain, 
+  with <%namespacename:defname> presenting a more HTML-like
+  alternative to calling defs, both plain and 
+  nested.  Many examples of the new syntax are in the
+  "Calling a def with embedded content" section
+  of the docs.
+  
+- added support for Jython 2.5.
+
+- cache module now uses Beaker's CacheManager
+  object directly, so that all cache types are included.
+  memcached is available as both "ext:memcached" and
+  "memcached", the latter for backwards compatibility.
+
+- added "cache" accessor to Template, Namespace.
+  e.g.  ${local.cache.get('somekey')} or
+  template.cache.invalidate_body()
+
+- added "cache_enabled=True" flag to Template, 
+  TemplateLookup.  Setting this to False causes cache
+  operations to "pass through" and execute every time;
+  this flag should be integrated in Pylons with its own
+  cache_enabled configuration setting.
+  
+- the Cache object now supports invalidate_def(name),
+  invalidate_body(), invalidate_closure(name), 
+  invalidate(key), which will remove the given key 
+  from the cache, if it exists.  The cache arguments
+  (i.e. storage type) are derived from whatever has
+  been already persisted for that template.
+  [ticket:92]
+
+- For cache changes to work fully, Beaker 1.1 is required.
+  1.0.1 and up will work as well with the exception of 
+  cache expiry.  Note that Beaker 1.1 is **required**
+  for applications which use dynamically generated keys,
+  since previous versions will permanently store state in memory 
+  for each individual key, thus consuming all available 
+  memory for an arbitrarily large number of distinct 
+  keys.
+
+- fixed bug whereby an <%included> template with 
+  <%page> args named the same as a __builtin__ would not
+  honor the default value specified in <%page> [ticket:93]
+  
+- fixed the html_error_template not handling tracebacks from
+  normal .py files with a magic encoding comment [ticket:88]
+
+- RichTraceback() now accepts an optional traceback object
+  to be used in place of sys.exc_info()[2].  html_error_template() 
+  and text_error_template() accept an optional
+  render()-time argument "traceback" which is passed to the
+  RichTraceback object.
+  
+- added ModuleTemplate class, which allows the construction
+  of a Template given a Python module generated by a previous
+  Template.   This allows Python modules alone to be used
+  as templates with no compilation step.   Source code
+  and template source are optional but allow error reporting
+  to work correctly.
+
+- fixed Python 2.3 compat. in mako.pyparser [ticket:90]
+
+- fix Babel 0.9.3 compatibility; stripping comment tags is now
+  optional (and enabled by default).
+
+
+0.2.2
+- cached blocks now use the current context when rendering
+an expired section, instead of the original context
+passed in [ticket:87]
+- fixed a critical issue regarding caching, whereby 
+a cached block would raise an error when called within a
+cache-refresh operation that was initiated after the 
+initiating template had completed rendering.
+
+0.2.1
+- fixed bug where 'output_encoding' parameter would prevent 
+render_unicode() from returning a unicode object.
+- bumped magic number, which forces template recompile for 
+this version (fixes incompatible compile symbols from 0.1 
+series).
+- added a few docs for cache options, specifically those that
+help with memcached.
+
+0.2.0
+- Speed improvements (as though we needed them, but people
+  contributed and there you go):
+
+  - added "bytestring passthru" mode, via
+    `disable_unicode=True` argument passed to Template or
+    TemplateLookup. All unicode-awareness and filtering is
+    turned off, and template modules are generated with
+    the appropriate magic encoding comment. In this mode,
+    template expressions can only receive raw bytestrings
+    or Unicode objects which represent straight ASCII, and
+    render_unicode() may not be used if multibyte
+    characters are present. When enabled, speed
+    improvement around 10-20%. [ticket:77] (courtesy
+    anonymous guest)
+
+  - inlined the "write" function of Context into a local
+    template variable. This affords a 12-30% speedup in
+    template render time. (idea courtesy same anonymous
+    guest) [ticket:76]
+  
+- New Features, API changes: 
+ 
+  - added "attr" accessor to namespaces. Returns
+    attributes configured as module level attributes, i.e.
+    within <%! %> sections.  [ticket:62] i.e.:
+    
+    # somefile.html
+    <%! 
+        foo = 27
+    %>
+    
+    # some other template
+    <%namespace name="myns" file="somefile.html"/>
+    ${myns.attr.foo}
+
+    The slight backwards incompatibility here is, you
+    can't have namespace defs named "attr" since the
+    "attr" descriptor will occlude it.
+    
+  - cache_key argument can now render arguments passed
+    directly to the %page or %def, i.e. <%def
+    name="foo(x)" cached="True" cache_key="${x}"/>
+    [ticket:78]
+
+  - some functions on Context are now private:
+    _push_buffer(), _pop_buffer(),
+    caller_stack._push_frame(), caller_stack._pop_frame().
+
+  - added a runner script "mako-render" which renders 
+    standard input as a template to stdout [ticket:81] 
+    [ticket:56]
+    
+- Bugfixes:
+  - can now use most names from __builtins__ as variable
+    names without explicit declaration (i.e. 'id', 
+    'exception', 'range', etc.) [ticket:83] [ticket:84]
+    
+  - can also use builtin names as local variable names 
+    (i.e. dict, locals) (came from fix for [ticket:84])
+    
+  - fixed bug in python generation when variable names are
+    used with identifiers like "else", "finally", etc.
+    inside them [ticket:68]
+
+  - fixed codegen bug which occured when using <%page>
+    level caching, combined with an expression-based
+    cache_key, combined with the usage of <%namespace
+    import="*"/> - fixed lexer exceptions not cleaning up
+    temporary files, which could lead to a maximum number
+    of file descriptors used in the process [ticket:69]
+
+  - fixed issue with inline format_exceptions that was
+    producing blank exception pages when an inheriting
+    template is present [ticket:71]
+  
+  - format_exceptions will apply the encoding options of
+    html_error_template() to the buffered output
+  
+  - rewrote the "whitespace adjuster" function to work
+    with more elaborate combinations of quotes and
+    comments [ticket:75]
+
+0.1.10
+- fixed propagation of 'caller' such that nested %def calls
+  within a <%call> tag's argument list propigates 'caller'
+  to the %call function itself (propigates to the inner
+  calls too, this is a slight side effect which previously
+  existed anyway)
+- fixed bug where local.get_namespace() could put an 
+  incorrect "self" in the current context
+- fixed another namespace bug where the namespace functions
+  did not have access to the correct context containing
+  their 'self' and 'parent'
+  
+0.1.9
+- filters.Decode filter can also accept a non-basestring
+object and will call str() + unicode() on it [ticket:47]
+- comments can be placed at the end of control lines,
+i.e. if foo: # a comment, [ticket:53], thanks to 
+Paul Colomiets
+- fixed expressions and page tag arguments and with embedded
+newlines in CRLF templates, follow up to [ticket:16], thanks
+Eric Woroshow
+- added an IOError catch for source file not found in RichTraceback
+exception reporter [ticket:51]
+
+0.1.8
+- variable names declared in render methods by internal 
+codegen prefixed by "__M_" to prevent name collisions
+with user code
+- added a Babel (http://babel.edgewall.org/) extractor entry
+point, allowing extraction of gettext messages directly from
+mako templates via Babel [ticket:45]
+- fix to turbogears plugin to work with dot-separated names
+(i.e. load_template('foo.bar')).  also takes file extension
+as a keyword argument (default is 'mak').
+- more tg fix:  fixed [ticket:35], allowing string-based
+templates with tgplugin even if non-compatible args were sent
+
+0.1.7
+- one small fix to the unit tests to support python 2.3
+- a slight hack to how cache.py detects Beaker's memcached, 
+works around unexplained import behavior observed on some 
+python 2.3 installations
+
+0.1.6 
+- caching is now supplied directly by Beaker, which has 
+  all of MyghtyUtils merged into it now.  The latest Beaker
+  (0.7.1) also fixes a bug related to how Mako was using the 
+  cache API.
+- fix to module_directory path generation when the path is "./"
+  [ticket:34]
+- TGPlugin passes options to string-based templates [ticket:35]
+- added an explicit stack frame step to template runtime, which
+  allows much simpler and hopefully bug-free tracking of 'caller',
+  fixes #28
+- if plain Python defs are used with <%call>, a decorator
+  @runtime.supports_callable exists to ensure that the "caller"
+  stack is properly handled for the def.
+- fix to RichTraceback and exception reporting to get template
+  source code as a unicode object #37
+- html_error_template includes options "full=True", "css=True"
+  which control generation of HTML tags, CSS [ticket:39]
+- added the 'encoding_errors' parameter to Template/TemplateLookup
+  for specifying the error handler associated with encoding to
+  'output_encoding' [ticket:40]
+- the Template returned by html_error_template now defaults to
+  output_encoding=sys.getdefaultencoding(),
+  encoding_errors='htmlentityreplace' [ticket:37]
+- control lines, i.e. % lines, support backslashes to continue long
+  lines (#32)
+- fixed codegen bug when defining <%def> within <%call> within <%call>
+- leading utf-8 BOM in template files is honored according to pep-0263
+  
+0.1.5
+- AST expression generation - added in just about everything 
+  expression-wise from the AST module  [ticket:26]
+- AST parsing, properly detects imports of the form "import foo.bar"
+  [ticket:27]
+- fix to lexing of <%docs> tag nested in other tags
+- fix to context-arguments inside of <%include> tag which broke 
+during 0.1.4 [ticket:29]
+- added "n" filter, disables *all* filters normally applied to an expression
+via <%page> or default_filters (but not those within the filter)
+- added buffer_filters argument, defines filters applied to the return value
+of buffered/cached/filtered %defs, after all filters defined with the %def
+itself have been applied.  allows the creation of default expression filters
+that let the output of return-valued %defs "opt out" of that filtering
+via passing special attributes or objects.
+  
+0.1.4
+- got defs-within-defs to be cacheable
+- fixes to code parsing/whitespace adjusting where plain python comments
+  may contain quote characters [ticket:23]
+- fix to variable scoping for identifiers only referenced within
+  functions
+- added a path normalization step to lookup so URIs like
+  "/foo/bar/../etc/../foo" pre-process the ".." tokens before checking
+  the filesystem
+- fixed/improved "caller" semantics so that undefined caller is
+  "UNDEFINED", propigates __nonzero__ method so it evaulates to False if
+  not present, True otherwise. this way you can say % if caller:\n
+  ${caller.body()}\n% endif
+- <%include> has an "args" attribute that can pass arguments to the
+  called template (keyword arguments only, must be declared in that
+  page's <%page> tag.)
+- <%include> plus arguments is also programmatically available via
+  self.include_file(<filename>, **kwargs)
+- further escaping added for multibyte expressions in %def, %call
+  attributes [ticket:24]
+
+
+0.1.3
+- ***Small Syntax Change*** - the single line comment character is now
+*two* hash signs, i.e. "## this is a comment".  This avoids a common
+collection with CSS selectors. 
+- the magic "coding" comment (i.e. # coding:utf-8) will still work with
+either one "#" sign or two for now; two is preferred going forward, i.e.
+## coding:<someencoding>. 
+- new multiline comment form: "<%doc> a comment </%doc>"
+- UNDEFINED evaluates to False
+- improvement to scoping of "caller" variable when using <%call> tag
+- added lexer error for unclosed control-line (%) line
+- added "preprocessor" argument to Template, TemplateLookup - is a single
+  callable or list of callables which will be applied to the template text
+  before lexing.  given the text as an argument, returns the new text.
+- added mako.ext.preprocessors package, contains one preprocessor so far:
+  'convert_comments', which will convert single # comments to the new ##
+  format
+  
+0.1.2
+- fix to parsing of code/expression blocks to insure that non-ascii
+  characters, combined with a template that indicates a non-standard
+  encoding, are expanded into backslash-escaped glyphs before being AST
+  parsed [ticket:11]
+- all template lexing converts the template to unicode first, to
+  immediately catch any encoding issues and ensure internal unicode
+  representation.
+- added module_filename argument to Template to allow specification of a
+  specific module file
+- added modulename_callable to TemplateLookup to allow a function to
+  determine module filenames (takes filename, uri arguments). used for
+  [ticket:14]
+- added optional input_encoding flag to Template, to allow sending a
+  unicode() object with no magic encoding comment
+- "expression_filter" argument in <%page> applies only to expressions
+- added "default_filters" argument to Template, TemplateLookup. applies only
+  to expressions, gets prepended to "expression_filter" arg from <%page>.
+  defaults to ["unicode"], so that all expressions get stringified into u''
+  by default (this is what Mako already does). By setting to [], expressions
+  are passed through raw.
+- added "imports" argument to Template, TemplateLookup. so you can predefine
+  a list of import statements at the top of the template. can be used in
+  conjunction with default_filters.
+- support for CRLF templates...whoops ! welcome to all the windows users.
+  [ticket:16]
+- small fix to local variable propigation for locals that are conditionally
+  declared
+- got "top level" def calls to work, i.e. template.get_def("somedef").render()
+
+0.1.1
+- buffet plugin supports string-based templates, allows ToscaWidgets to work
+  [ticket:8]
+- AST parsing fixes: fixed TryExcept identifier parsing
+- removed textmate tmbundle from contrib and into separate SVN location;
+  windows users cant handle those files, setuptools not very good at
+  "pruning" certain directories
+- fix so that "cache_timeout" parameter is propigated
+- fix to expression filters so that string conversion (actually unicode)
+  properly occurs before filtering
+- better error message when a lookup is attempted with a template that has no
+  lookup
+- implemented "module" attribute for namespace
+- fix to code generation to correctly track multiple defs with the same name
+- "directories" can be passed to TemplateLookup as a scalar in which case it
+  gets converted to a list [ticket:9]
+
+0.1.0
+
+Initial release.
diff --git a/lib3/mako-0.3.6/LICENSE b/lib3/mako-0.3.6/LICENSE
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/LICENSE
@@ -0,0 +1,20 @@
+This is the MIT license: http://www.opensource.org/licenses/mit-license.php
+
+Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer and contributors.
+Mako is a trademark of Michael Bayer.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this
+software and associated documentation files (the "Software"), to deal in the Software
+without restriction, including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/lib3/mako-0.3.6/MANIFEST.in b/lib3/mako-0.3.6/MANIFEST.in
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/MANIFEST.in
@@ -0,0 +1,12 @@
+# any kind of "*" pulls in __init__.pyc files,
+# so all extensions are explicit.
+
+recursive-include doc *.html *.css *.txt *.js *.jpg *.png *.py Makefile *.rst *.mako *.sty autohandler
+recursive-include examples *.py *.xml *.mako *.myt *.kid *.tmpl
+recursive-include test *.py *.dat *.html *.mako
+
+include README* LICENSE distribute_setup.py ez_setup.py CHANGES*
+
+# when we go to sphinx
+#prune doc/build/output
+
diff --git a/lib3/mako-0.3.6/README b/lib3/mako-0.3.6/README
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/README
@@ -0,0 +1,25 @@
+Mako is licensed under an MIT-style license (see LICENSE).
+Other incorporated projects may be licensed under different licenses.
+All licenses allow for non-commercial and commercial use.
+
+To install:
+
+    python setup.py install
+
+SVN checkouts also inlcude setup.cfg file allowing setuptools to create 
+an svn-tagged build.  
+
+Documentation is available in HTML format in the ./doc/ directory.
+
+Unit tests run via nose, and are available via setup.py:
+
+    python setup.py test
+        
+Or direct nose usage:
+
+    nosetests -v
+
+For Python 3 information, see README.py3k.
+
+good luck !
+
diff --git a/lib3/mako-0.3.6/README.py3k b/lib3/mako-0.3.6/README.py3k
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/README.py3k
@@ -0,0 +1,56 @@
+=================
+PYTHON 3 SUPPORT
+=================
+
+Python 3 support in Mako is provided by the Python 2to3 script.
+
+Installing Distribute
+---------------------
+
+Distribute should be installed with the Python3 installation.  The
+distribute bootloader is included.
+
+Running as a user with permission to modify the Python distribution,
+install Distribute:
+
+    python3 distribute_setup.py
+
+Installing Mako in Python 3
+---------------------------------
+
+Once Distribute is installed, Mako can be installed directly.  
+The 2to3 process will kick in which takes several minutes:
+
+    python3 setup.py install
+
+Converting Tests, Examples, Source to Python 3
+----------------------------------------------
+
+To convert all files in the source distribution, run 
+the 2to3 script:
+
+    2to3 -w mako test
+
+If using 3.1's 2to3 tool, the --no-diffs flag might help 
+with unicode issues:
+
+    2to3-3.1 -w --no-diffs mako test
+    
+The above will rewrite all files in-place in Python 3 format.
+
+Running Tests
+-------------
+
+To run the unit tests, ensure Distribute is installed as above,
+and also that at least the ./mako/ and ./test/ directories have been converted
+to Python 3 using the source tool above.   A Python 3 version of Nose
+can be acquired from Bitbucket using Mercurial:
+
+    hg clone http://bitbucket.org/jpellerin/nose3/
+    cd nose3
+    python3 setup.py install
+
+The tests can then be run using the "nosetests3" script installed 
+by the above (python3 setup.py test doesn't seem to be working with 
+nose3).
+
diff --git a/lib3/mako-0.3.6/distribute_setup.py b/lib3/mako-0.3.6/distribute_setup.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/distribute_setup.py
@@ -0,0 +1,485 @@
+#!python
+"""Bootstrap distribute installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+    from distribute_setup import use_setuptools
+    use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import os
+import sys
+import time
+import fnmatch
+import tempfile
+import tarfile
+from distutils import log
+
+try:
+    from site import USER_SITE
+except ImportError:
+    USER_SITE = None
+
+try:
+    import subprocess
+
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        return subprocess.call(args) == 0
+
+except ImportError:
+    # will be used for python 2.3
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        # quoting arguments if windows
+        if sys.platform == 'win32':
+            def quote(arg):
+                if ' ' in arg:
+                    return '"%s"' % arg
+                return arg
+            args = [quote(arg) for arg in args]
+        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
+
+DEFAULT_VERSION = "0.6.13"
+DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
+SETUPTOOLS_FAKED_VERSION = "0.6c11"
+
+SETUPTOOLS_PKG_INFO = """\
+Metadata-Version: 1.0
+Name: setuptools
+Version: %s
+Summary: xxxx
+Home-page: xxx
+Author: xxx
+Author-email: xxx
+License: xxx
+Description: xxx
+""" % SETUPTOOLS_FAKED_VERSION
+
+
+def _install(tarball):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # installing
+        log.warn('Installing Distribute')
+        if not _python_cmd('setup.py', 'install'):
+            log.warn('Something went wrong during the installation.')
+            log.warn('See the error message above.')
+    finally:
+        os.chdir(old_wd)
+
+
+def _build_egg(egg, tarball, to_dir):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # building an egg
+        log.warn('Building a Distribute egg in %s', to_dir)
+        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
+
+    finally:
+        os.chdir(old_wd)
+    # returning the result
+    log.warn(egg)
+    if not os.path.exists(egg):
+        raise IOError('Could not build the egg.')
+
+
+def _do_download(version, download_base, to_dir, download_delay):
+    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
+                       % (version, sys.version_info[0], sys.version_info[1]))
+    if not os.path.exists(egg):
+        tarball = download_setuptools(version, download_base,
+                                      to_dir, download_delay)
+        _build_egg(egg, tarball, to_dir)
+    sys.path.insert(0, egg)
+    import setuptools
+    setuptools.bootstrap_install_from = egg
+
+
+def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                   to_dir=os.curdir, download_delay=15, no_fake=True):
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    was_imported = 'pkg_resources' in sys.modules or \
+        'setuptools' in sys.modules
+    try:
+        try:
+            import pkg_resources
+            if not hasattr(pkg_resources, '_distribute'):
+                if not no_fake:
+                    _fake_setuptools()
+                raise ImportError
+        except ImportError:
+            return _do_download(version, download_base, to_dir, download_delay)
+        try:
+            pkg_resources.require("distribute>="+version)
+            return
+        except pkg_resources.VersionConflict:
+            e = sys.exc_info()[1]
+            if was_imported:
+                sys.stderr.write(
+                "The required version of distribute (>=%s) is not available,\n"
+                "and can't be installed while this script is running. Please\n"
+                "install a more recent version first, using\n"
+                "'easy_install -U distribute'."
+                "\n\n(Currently using %r)\n" % (version, e.args[0]))
+                sys.exit(2)
+            else:
+                del pkg_resources, sys.modules['pkg_resources']    # reload ok
+                return _do_download(version, download_base, to_dir,
+                                    download_delay)
+        except pkg_resources.DistributionNotFound:
+            return _do_download(version, download_base, to_dir,
+                                download_delay)
+    finally:
+        if not no_fake:
+            _create_fake_setuptools_pkg_info(to_dir)
+
+def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                        to_dir=os.curdir, delay=15):
+    """Download distribute from a specified location and return its filename
+
+    `version` should be a valid distribute version number that is available
+    as an egg for download under the `download_base` URL (which should end
+    with a '/'). `to_dir` is the directory where the egg will be downloaded.
+    `delay` is the number of seconds to pause before an actual download
+    attempt.
+    """
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    try:
+        from urllib.request import urlopen
+    except ImportError:
+        from urllib.request import urlopen
+    tgz_name = "distribute-%s.tar.gz" % version
+    url = download_base + tgz_name
+    saveto = os.path.join(to_dir, tgz_name)
+    src = dst = None
+    if not os.path.exists(saveto):  # Avoid repeated downloads
+        try:
+            log.warn("Downloading %s", url)
+            src = urlopen(url)
+            # Read/write all in one block, so we don't create a corrupt file
+            # if the download is interrupted.
+            data = src.read()
+            dst = open(saveto, "wb")
+            dst.write(data)
+        finally:
+            if src:
+                src.close()
+            if dst:
+                dst.close()
+    return os.path.realpath(saveto)
+
+def _no_sandbox(function):
+    def __no_sandbox(*args, **kw):
+        try:
+            from setuptools.sandbox import DirectorySandbox
+            if not hasattr(DirectorySandbox, '_old'):
+                def violation(*args):
+                    pass
+                DirectorySandbox._old = DirectorySandbox._violation
+                DirectorySandbox._violation = violation
+                patched = True
+            else:
+                patched = False
+        except ImportError:
+            patched = False
+
+        try:
+            return function(*args, **kw)
+        finally:
+            if patched:
+                DirectorySandbox._violation = DirectorySandbox._old
+                del DirectorySandbox._old
+
+    return __no_sandbox
+
+def _patch_file(path, content):
+    """Will backup the file then patch it"""
+    existing_content = open(path).read()
+    if existing_content == content:
+        # already patched
+        log.warn('Already patched.')
+        return False
+    log.warn('Patching...')
+    _rename_path(path)
+    f = open(path, 'w')
+    try:
+        f.write(content)
+    finally:
+        f.close()
+    return True
+
+_patch_file = _no_sandbox(_patch_file)
+
+def _same_content(path, content):
+    return open(path).read() == content
+
+def _rename_path(path):
+    new_name = path + '.OLD.%s' % time.time()
+    log.warn('Renaming %s into %s', path, new_name)
+    os.rename(path, new_name)
+    return new_name
+
+def _remove_flat_installation(placeholder):
+    if not os.path.isdir(placeholder):
+        log.warn('Unkown installation at %s', placeholder)
+        return False
+    found = False
+    for file in os.listdir(placeholder):
+        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
+            found = True
+            break
+    if not found:
+        log.warn('Could not locate setuptools*.egg-info')
+        return
+
+    log.warn('Removing elements out of the way...')
+    pkg_info = os.path.join(placeholder, file)
+    if os.path.isdir(pkg_info):
+        patched = _patch_egg_dir(pkg_info)
+    else:
+        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
+
+    if not patched:
+        log.warn('%s already patched.', pkg_info)
+        return False
+    # now let's move the files out of the way
+    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
+        element = os.path.join(placeholder, element)
+        if os.path.exists(element):
+            _rename_path(element)
+        else:
+            log.warn('Could not find the %s element of the '
+                     'Setuptools distribution', element)
+    return True
+
+_remove_flat_installation = _no_sandbox(_remove_flat_installation)
+
+def _after_install(dist):
+    log.warn('After install bootstrap.')
+    placeholder = dist.get_command_obj('install').install_purelib
+    _create_fake_setuptools_pkg_info(placeholder)
+
+def _create_fake_setuptools_pkg_info(placeholder):
+    if not placeholder or not os.path.exists(placeholder):
+        log.warn('Could not find the install location')
+        return
+    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
+    setuptools_file = 'setuptools-%s-py%s.egg-info' % \
+            (SETUPTOOLS_FAKED_VERSION, pyver)
+    pkg_info = os.path.join(placeholder, setuptools_file)
+    if os.path.exists(pkg_info):
+        log.warn('%s already exists', pkg_info)
+        return
+
+    log.warn('Creating %s', pkg_info)
+    f = open(pkg_info, 'w')
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+
+    pth_file = os.path.join(placeholder, 'setuptools.pth')
+    log.warn('Creating %s', pth_file)
+    f = open(pth_file, 'w')
+    try:
+        f.write(os.path.join(os.curdir, setuptools_file))
+    finally:
+        f.close()
+
+_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
+
+def _patch_egg_dir(path):
+    # let's check if it's already patched
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    if os.path.exists(pkg_info):
+        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
+            log.warn('%s already patched.', pkg_info)
+            return False
+    _rename_path(path)
+    os.mkdir(path)
+    os.mkdir(os.path.join(path, 'EGG-INFO'))
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    f = open(pkg_info, 'w')
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+    return True
+
+_patch_egg_dir = _no_sandbox(_patch_egg_dir)
+
+def _before_install():
+    log.warn('Before install bootstrap.')
+    _fake_setuptools()
+
+
+def _under_prefix(location):
+    if 'install' not in sys.argv:
+        return True
+    args = sys.argv[sys.argv.index('install')+1:]
+    for index, arg in enumerate(args):
+        for option in ('--root', '--prefix'):
+            if arg.startswith('%s=' % option):
+                top_dir = arg.split('root=')[-1]
+                return location.startswith(top_dir)
+            elif arg == option:
+                if len(args) > index:
+                    top_dir = args[index+1]
+                    return location.startswith(top_dir)
+        if arg == '--user' and USER_SITE is not None:
+            return location.startswith(USER_SITE)
+    return True
+
+
+def _fake_setuptools():
+    log.warn('Scanning installed packages')
+    try:
+        import pkg_resources
+    except ImportError:
+        # we're cool
+        log.warn('Setuptools or Distribute does not seem to be installed.')
+        return
+    ws = pkg_resources.working_set
+    try:
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
+                                  replacement=False))
+    except TypeError:
+        # old distribute API
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+
+    if setuptools_dist is None:
+        log.warn('No setuptools distribution found')
+        return
+    # detecting if it was already faked
+    setuptools_location = setuptools_dist.location
+    log.warn('Setuptools installation detected at %s', setuptools_location)
+
+    # if --root or --preix was provided, and if
+    # setuptools is not located in them, we don't patch it
+    if not _under_prefix(setuptools_location):
+        log.warn('Not patching, --root or --prefix is installing Distribute'
+                 ' in another location')
+        return
+
+    # let's see if its an egg
+    if not setuptools_location.endswith('.egg'):
+        log.warn('Non-egg installation')
+        res = _remove_flat_installation(setuptools_location)
+        if not res:
+            return
+    else:
+        log.warn('Egg installation')
+        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
+        if (os.path.exists(pkg_info) and
+            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
+            log.warn('Already patched.')
+            return
+        log.warn('Patching...')
+        # let's create a fake egg replacing setuptools one
+        res = _patch_egg_dir(setuptools_location)
+        if not res:
+            return
+    log.warn('Patched done.')
+    _relaunch()
+
+
+def _relaunch():
+    log.warn('Relaunching...')
+    # we have to relaunch the process
+    # pip marker to avoid a relaunch bug
+    if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
+        sys.argv[0] = 'setup.py'
+    args = [sys.executable] + sys.argv
+    sys.exit(subprocess.call(args))
+
+
+def _extractall(self, path=".", members=None):
+    """Extract all members from the archive to the current working
+       directory and set owner, modification time and permissions on
+       directories afterwards. `path' specifies a different directory
+       to extract to. `members' is optional and must be a subset of the
+       list returned by getmembers().
+    """
+    import copy
+    import operator
+    from tarfile import ExtractError
+    directories = []
+
+    if members is None:
+        members = self
+
+    for tarinfo in members:
+        if tarinfo.isdir():
+            # Extract directories with a safe mode.
+            directories.append(tarinfo)
+            tarinfo = copy.copy(tarinfo)
+            tarinfo.mode = 448 # decimal for oct 0700
+        self.extract(tarinfo, path)
+
+    # Reverse sort directories.
+    if sys.version_info < (2, 4):
+        def sorter(dir1, dir2):
+            return cmp(dir1.name, dir2.name)
+        directories.sort(sorter)
+        directories.reverse()
+    else:
+        directories.sort(key=operator.attrgetter('name'), reverse=True)
+
+    # Set correct owner, mtime and filemode on directories.
+    for tarinfo in directories:
+        dirpath = os.path.join(path, tarinfo.name)
+        try:
+            self.chown(tarinfo, dirpath)
+            self.utime(tarinfo, dirpath)
+            self.chmod(tarinfo, dirpath)
+        except ExtractError:
+            e = sys.exc_info()[1]
+            if self.errorlevel > 1:
+                raise
+            else:
+                self._dbg(1, "tarfile: %s" % e)
+
+
+def main(argv, version=DEFAULT_VERSION):
+    """Install or upgrade setuptools and EasyInstall"""
+    tarball = download_setuptools()
+    _install(tarball)
+
+
+if __name__ == '__main__':
+    main(sys.argv[1:])
diff --git a/lib3/mako-0.3.6/doc/build/Makefile b/lib3/mako-0.3.6/doc/build/Makefile
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/Makefile
@@ -0,0 +1,143 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = output
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest dist-html site-mako
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dist-html  same as html, but places files in /doc"
+	@echo "  site-mako  build Mako files for usage on the Mako site"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html -A mako_layout=html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dist-html:
+	$(SPHINXBUILD) -b html -A mako_layout=html $(ALLSPHINXOPTS) ..
+	@echo
+	@echo "Build finished.  The HTML pages are in ../."
+
+site-mako:
+	$(SPHINXBUILD) -b html -A mako_layout=site $(ALLSPHINXOPTS) $(BUILDDIR)/site
+	@echo
+	@echo "Build finished. The Mako pages are in $(BUILDDIR)/site."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/SQLAlchemy.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/SQLAlchemy.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/SQLAlchemy"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/SQLAlchemy"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	cp texinputs/* $(BUILDDIR)/latex/
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	make -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) .
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/lib3/mako-0.3.6/doc/build/builder/builders.py b/lib3/mako-0.3.6/doc/build/builder/builders.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/builder/builders.py
@@ -0,0 +1,69 @@
+from sphinx.application import TemplateBridge
+from sphinx.builders.html import StandaloneHTMLBuilder
+from sphinx.highlighting import PygmentsBridge
+from pygments import highlight
+from pygments.lexer import RegexLexer, bygroups, using
+from pygments.token import *
+from pygments.filter import Filter, apply_filters
+from pygments.lexers import PythonLexer, PythonConsoleLexer
+from pygments.formatters import HtmlFormatter, LatexFormatter
+import re
+from mako.lookup import TemplateLookup
+from mako.template import Template
+from mako.ext.pygmentplugin import MakoLexer
+
+class MakoBridge(TemplateBridge):
+    def init(self, builder, *args, **kw):
+        self.layout = builder.config.html_context.get('mako_layout', 'html')
+        
+        self.lookup = TemplateLookup(directories=builder.config.templates_path,
+            format_exceptions=True, 
+            imports=[
+                "from builder import util"
+            ]
+        )
+        
+    def render(self, template, context):
+        template = template.replace(".html", ".mako")
+        context['prevtopic'] = context.pop('prev', None)
+        context['nexttopic'] = context.pop('next', None)
+        context['mako_layout'] = self.layout == 'html' and 'static_base.mako' or 'site_base.mako'
+        # sphinx 1.0b2 doesn't seem to be providing _ for some reason...
+        context.setdefault('_', lambda x:x)
+        return self.lookup.get_template(template).render_unicode(**context)
+        
+    
+    def render_string(self, template, context):
+        context['prevtopic'] = context.pop('prev', None)
+        context['nexttopic'] = context.pop('next', None)
+        context['mako_layout'] = self.layout == 'html' and 'static_base.mako' or 'site_base.mako'
+        # sphinx 1.0b2 doesn't seem to be providing _ for some reason...
+        context.setdefault('_', lambda x:x)
+        return Template(template, lookup=self.lookup,
+            format_exceptions=True, 
+            imports=[
+                "from builder import util"
+            ]
+        ).render_unicode(**context)
+        
+class StripDocTestFilter(Filter):
+    def filter(self, lexer, stream):
+        for ttype, value in stream:
+            if ttype is Token.Comment and re.match(r'#\s*doctest:', value):
+                continue
+            yield ttype, value
+
+
+def autodoc_skip_member(app, what, name, obj, skip, options):
+    if what == 'class' and skip and name == '__init__':
+        return False
+    else:
+        return skip
+
+def setup(app):
+#    app.connect('autodoc-skip-member', autodoc_skip_member)
+    # Mako is already in Pygments, adding the local
+    # lexer here so that the latest syntax is available
+    app.add_lexer('mako', MakoLexer())
+    
+    
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/doc/build/builder/util.py b/lib3/mako-0.3.6/doc/build/builder/util.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/builder/util.py
@@ -0,0 +1,12 @@
+import re
+
+def striptags(text):
+    return re.compile(r'<[^>]*>').sub('', text)
+
+def go(m):
+    # .html with no anchor if present, otherwise "#" for top of page
+    return m.group(1) or '#'
+    
+def strip_toplevel_anchors(text):
+    return re.compile(r'(\.html)?#[-\w]+-toplevel').sub(go, text)
+    
diff --git a/lib3/mako-0.3.6/doc/build/caching.rst b/lib3/mako-0.3.6/doc/build/caching.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/caching.rst
@@ -0,0 +1,127 @@
+.. _caching_toplevel:
+
+========
+Caching
+========
+
+Any template or component can be cached using the ``cache``
+argument to the ``<%page>`` or ``<%def>`` directives:
+
+.. sourcecode:: mako
+
+    <%page cached="True"/>
+    
+    template text
+    
+The above template, after being executed the first time, will
+store its content within a cache that by default is scoped
+within memory. Subsequent calls to the template's :meth:`~.Template.render`
+method will return content directly from the cache. When the
+:class:`.Template` object itself falls out of scope, its corresponding
+cache is garbage collected along with the template.
+
+Caching requires that the ``beaker`` package be installed on the
+system.
+
+The caching flag and all its options can be used with the
+``<%def>`` tag.
+
+.. sourcecode:: mako
+
+    <%def name="mycomp" cached="True" cache_timeout="30" cache_type="memory">
+        other text
+    </%def>
+
+Cache arguments
+================
+
+The various cache arguments are cascaded from their default
+values, to the arguments specified programmatically to the
+:class:`.Template` or its originating :class:`.TemplateLookup`, then to those
+defined in the ``<%page>`` tag of an individual template, and
+finally to an individual ``<%def>`` tag within the template. This
+means you can define, for example, a cache type of ``dbm`` on your
+:class:`.TemplateLookup`, a cache timeout of 60 seconds in a particular
+template's ``<%page>`` tag, and within one of that template's
+``<%def>`` tags ``cache=True``, and that one particular def will
+then cache its data using a ``dbm`` cache and a data timeout of 60
+seconds.
+
+The options available are:
+
+* ``cached="False|True"`` - turn caching on
+* ``cache_timeout`` - number of seconds in which to invalidate the
+  cached data. after this timeout, the content is re-generated
+  on the next call.
+* ``cache_type`` - type of caching. ``memory``, ``file``, ``dbm``, or
+  ``memcached``.
+* ``cache_url`` - (only used for ``memcached`` but required) a single
+  IP address or a semi-colon separated list of IP address of
+  memcache servers to use.
+* ``cache_dir`` - In the case of the ``file`` and ``dbm`` cache types,
+  this is the filesystem directory with which to store data
+  files. If this option is not present, the value of
+  ``module_directory`` is used (i.e. the directory where compiled
+  template modules are stored). If neither option is available
+  an exception is thrown.
+  
+  In the case of the ``memcached`` type, this attribute is required
+  and it's used to store the lock files.
+* ``cache_key`` - the "key" used to uniquely identify this content
+  in the cache. the total namespace of keys within the cache is
+  local to the current template, and the default value of "key"
+  is the name of the def which is storing its data. It is an
+  evaluable tag, so you can put a Python expression to calculate
+  the value of the key on the fly. For example, heres a page
+  that caches any page which inherits from it, based on the
+  filename of the calling template:
+    
+.. sourcecode:: mako
+
+    <%page cached="True" cache_key="${self.filename}"/>
+
+    ${next.body()}
+    
+    ## rest of template
+    
+Accessing the Cache
+===================
+
+The :class:`.Template`, as well as any template-derived namespace, has
+an accessor called ``cache`` which returns the ``Cache`` object
+for that template. This object is a facade on top of the Beaker
+internal cache object, and provides some very rudimental
+capabilities, such as the ability to get and put arbitrary
+values:
+
+.. sourcecode:: mako
+
+    <%
+        local.cache.put("somekey", type="memory", "somevalue")
+    %>
+    
+Above, the cache associated with the ``local`` namespace is
+accessed and a key is placed within a memory cache.
+
+More commonly the ``cache`` object is used to invalidate cached
+sections programmatically:
+
+.. sourcecode:: python
+
+    template = lookup.get_template('/sometemplate.html')
+    
+    # invalidate the "body" of the template
+    template.cache.invalidate_body()
+    
+    # invalidate an individual def
+    template.cache.invalidate_def('somedef')
+    
+    # invalidate an arbitrary key
+    template.cache.invalidate('somekey')
+    
+API Reference
+==============
+
+.. autoclass:: mako.cache.Cache
+    :members:
+    :show-inheritance:
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/doc/build/conf.py b/lib3/mako-0.3.6/doc/build/conf.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/conf.py
@@ -0,0 +1,280 @@
+# -*- coding: utf-8 -*-
+#
+# Mako documentation build configuration file
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+sys.path.insert(0, os.path.abspath('../..'))
+sys.path.insert(0, os.path.abspath('.'))
+
+import mako
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+#extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode',
+#                'sphinx.ext.doctest', 'builder.builders']
+
+extensions = ['sphinx.ext.autodoc',
+                'sphinx.ext.doctest', 'builder.builders']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['templates']
+
+nitpicky = True
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+template_bridge = "builder.builders.MakoBridge"
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'Mako'
+copyright = 'the Mako authors and contributors'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = mako.__version__
+# The full version, including alpha/beta/rc tags.
+release = mako.__version__
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'default.css'
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+html_title = "%s %s Documentation" % (project, release)
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%m/%d/%Y %H:%M:%S'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+html_domain_indices = False
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Makodoc'
+
+#autoclass_content = 'both'
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'mako_%s.tex' % release.replace('.', '_'), r'Mako Documentation',
+   r'Mike Bayer', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+# sets TOC depth to 2.
+latex_preamble = '\setcounter{tocdepth}{3}'
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+#latex_elements = {
+#    'papersize': 'letterpaper',
+#    'pointsize': '10pt',
+#}
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'mako', 'Mako Documentation',
+     ['Mako authors'], 1)
+]
+
+
+# -- Options for Epub output ---------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = 'Mako'
+epub_author = 'Mako authors'
+epub_publisher = 'Mako authors'
+epub_copyright = 'Mako authors'
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+#epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#epub_identifier = ''
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+#epub_exclude_files = []
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#epub_tocdup = True
diff --git a/lib3/mako-0.3.6/doc/build/defs.rst b/lib3/mako-0.3.6/doc/build/defs.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/defs.rst
@@ -0,0 +1,436 @@
+.. _defs_toplevel:
+
+====
+Defs
+====
+
+``<%def>`` is the single tag used to demarcate any block of text
+and/or code. It exists within generated Python as a callable
+function:
+
+.. sourcecode:: mako
+
+    <%def name="hello()">
+        hello world
+    </%def>
+
+They are normally called as expressions:
+
+.. sourcecode:: mako
+
+    the def:  ${hello()}
+
+If the ``<%def>`` is not nested inside of another ``<%def>``,
+its known as a **top level def** and can be accessed anywhere in
+the template, including above where it was defined.
+
+All defs, top level or not, have access to the current
+contextual namespace in exactly the same way their containing
+template does. Suppose the template below is executed with the
+variables ``username`` and ``accountdata`` inside the context:
+
+.. sourcecode:: mako
+
+    Hello there ${username}, how are ya.  Lets see what your account says:
+    
+    ${account()}
+
+    <%def name="account()">
+        Account for ${username}:<br/>
+    
+        % for row in accountdata:
+            Value: ${row}<br/>
+        % endfor
+    </%def>
+
+The ``username`` and ``accountdata`` variables are present
+within the main template body as well as the body of the
+``account()`` def.
+
+Since defs are just Python functions, you can define and pass
+arguments to them as well:
+
+.. sourcecode:: mako
+
+    ${account(accountname='john')}
+    
+    <%def name="account(accountname, type='regular')">
+        account name: ${accountname}, type ${type}
+    </%def>
+
+When you declare an argument signature for your def, they are
+required to follow normal Python conventions (i.e., all
+arguments are required except keyword arguments with a default
+value). This is in contrast to using context-level variables,
+which evaluate to ``UNDEFINED`` if you reference a name that
+does not exist.
+
+Calling defs from Other Files 
+==============================
+
+Top level ``<%defs>`` are **exported** by your template's
+module, and can be called from the outside; including from other
+templates, as well as normal Python code. Calling a ``<%def>``
+from another template is something like using an ``<%include>``
+- except you are calling a specific function within the
+template, not the whole template.
+
+The remote ``<%def>`` call is also a little bit like calling
+functions from other modules in Python. There is an "import"
+step to pull the names from another template into your own
+template; then the function or functions are available.
+
+To import another template, use the ``<%namespace>`` tag:
+
+.. sourcecode:: mako
+
+    <%namespace name="mystuff" file="mystuff.html"/>
+
+The above tag adds a local variable "mystuff" to the current
+scope.
+
+Then, just call the defs off of ``mystuff``:
+
+.. sourcecode:: mako
+
+    ${mystuff.somedef(x=5,y=7)}
+
+The ``<%namespace>`` tag also supports some of the other
+semantics of Python's ``import`` statement, including pulling
+names into the local variable space, or using ``*`` to represent
+all names, using the ``import`` attribute:
+
+.. sourcecode:: mako
+
+    <%namespace file="mystuff.html" import="foo, bar"/>
+
+This is just a quick intro to the concept of a **namespace**,
+which is a central Mako concept that has its own chapter in
+these docs. For more detail and examples, see
+:ref:`namespaces_toplevel`.
+
+Calling defs programmatically
+==============================
+
+You can call def's programmatically from any :class:`.Template` object
+using the :meth:`~.Template.get_def()` method, which returns a :class:`.DefTemplate`
+object. This is a :class:`.Template` subclass which the parent
+:class:`.Template` creates, and is usable like any other template:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    
+    template = Template("""
+        <%def name="hi(name)">
+            hi ${name}!
+        </%def>
+        
+        <%def name="bye(name)">
+            bye ${name}!
+        </%def>
+    """)
+    
+    print template.get_def("hi").render(name="ed")
+    print template.get_def("bye").render(name="ed")
+    
+
+Defs within Defs
+================
+
+The def model follows regular Python rules for closures.
+Declaring ``<%def>`` inside another ``<%def>`` declares it
+within the parent's **enclosing scope**:
+
+.. sourcecode:: mako
+
+    <%def name="mydef()">
+        <%def name="subdef()">
+            a sub def
+        </%def>
+        
+        im the def, and the subcomponent is ${subdef()}
+    </%def>
+
+Just like Python, names that exist outside the inner ``<%def>``
+exist inside it as well:
+
+.. sourcecode:: mako
+
+    <%
+        x = 12
+    %>
+    <%def name="outer()">
+        <%
+            y = 15
+        %>
+        <%def name="inner()">
+            inner, x is ${x}, y is ${y}
+        </%def>
+
+        outer, x is ${x}, y is ${y}
+    </%def>
+
+Assigning to a name inside of a def declares that name as local
+to the scope of that def (again, like Python itself). This means
+the following code will raise an error:
+
+.. sourcecode:: mako
+
+    <%
+        x = 10
+    %>
+    <%def name="somedef()">
+        ## error !
+        somedef, x is ${x}  
+        <%
+            x = 27  
+        %>
+    </%def>
+
+...because the assignment to ``x`` declares x as local to the
+scope of ``somedef``, rendering the "outer" version unreachable
+in the expression that tries to render it.
+
+.. _defs_with_content:
+
+Calling a def with embedded content and/or other defs
+=====================================================
+
+A flip-side to def within def is a def call with content. This
+is where you call a def, and at the same time declare a block of
+content (or multiple blocks) that can be used by the def being
+called. The main point of such a call is to create custom,
+nestable tags, just like any other template language's
+custom-tag creation system - where the external tag controls the
+execution of the nested tags and can communicate state to them.
+Only with Mako, you don't have to use any external Python
+modules, you can define arbitrarily nestable tags right in your
+templates.
+
+To achieve this, the target def is invoked using the form
+``<%namepacename:defname>`` instead of the normal ``${}``
+syntax. This syntax, introduced in Mako 0.2.3, is functionally
+equivalent another tag known as ``call``, which takes the form
+``<%call expr='namespacename.defname(args)'>``. While ``%call``
+is available in all versions of Mako, the newer style is
+probably more familiar looking. The ``namespace`` portion of the
+call is the name of the **namespace** in which the def is
+defined - in the most simple cases, this can be ``local`` or
+``self`` to reference the current template's namespace (the
+difference between ``local`` and ``self`` is one of inheritance
+- see :ref:`namespaces_builtin` for details).
+
+When the target def is invoked, a variable ``caller`` is placed
+in its context which contains another namespace containing the
+body and other defs defined by the caller. The body itself is
+referenced by the method ``body()``. Below, we build a ``%def``
+that operates upon ``caller.body()`` to invoke the body of the
+custom tag:
+
+.. sourcecode:: mako
+
+    <%def name="buildtable()">
+        <table>
+            <tr><td>
+                ${caller.body()}
+            </td></tr>
+        </table>
+    </%def>
+    
+    <%self:buildtable>
+        I am the table body.
+    </%self:buildtable>
+    
+This produces the output (whitespace formatted):
+
+.. sourcecode:: html
+
+    <table>
+        <tr><td>
+            I am the table body.
+        </td></tr>
+    </table>
+
+Using the older ``%call`` syntax looks like:
+
+.. sourcecode:: mako
+
+    <%def name="buildtable()">
+        <table>
+            <tr><td>
+                ${caller.body()}
+            </td></tr>
+        </table>
+    </%def>
+
+    <%call expr="buildtable()">
+        I am the table body.
+    </%call>
+
+The ``body()`` can be executed multiple times or not at all.
+This means you can use def-call-with-content to build iterators,
+conditionals, etc:
+
+.. sourcecode:: mako
+
+    <%def name="lister(count)">
+        % for x in range(count):
+            ${caller.body()}
+        % endfor
+    </%def>
+    
+    <%self:lister count="${3}">
+        hi
+    </%self:lister>
+    
+Produces:
+    
+.. sourcecode:: html
+
+    hi
+    hi
+    hi
+
+Notice above we pass ``3`` as a Python expression, so that it
+remains as an integer.
+
+A custom "conditional" tag:
+    
+.. sourcecode:: mako
+
+    <%def name="conditional(expression)">
+        % if expression:
+            ${caller.body()}
+        % endif
+    </%def>
+
+    <%self:conditional expression="${4==4}">
+        im the result
+    </%self:conditional>
+
+Produces:
+
+.. sourcecode:: html
+
+    im the result
+
+But that's not all. The ``body()`` function also can handle
+arguments, which will augment the local namespace of the body
+callable. The caller must define the arguments which it expects
+to receive from its target def using the ``args`` attribute,
+which is a comma-separated list of argument names. Below, our
+``<%def>`` calls the ``body()`` of its caller, passing in an
+element of data from its argument:
+
+.. sourcecode:: mako
+
+    <%def name="layoutdata(somedata)">
+        <table>
+        % for item in somedata:
+            <tr>
+            % for col in item:
+                <td>${caller.body(col=col)}</td>
+            % endfor
+            </tr>
+        % endfor
+        </table>
+    </%def>
+
+    <%self:layoutdata somedata="${[[1,2,3],[4,5,6],[7,8,9]]}" args="col">\
+    Body data: ${col}\
+    </%self:layoutdata>
+    
+Produces:
+
+.. sourcecode:: html
+
+    <table>
+       <tr>
+           <td>Body data: 1</td>
+           <td>Body data: 2</td>
+           <td>Body data: 3</td>
+       </tr>
+       <tr>
+           <td>Body data: 4</td>
+           <td>Body data: 5</td>
+           <td>Body data: 6</td>
+       </tr>
+       <tr>
+           <td>Body data: 7</td>
+           <td>Body data: 8</td>
+           <td>Body data: 9</td>
+       </tr>
+    </table>
+    
+You don't have to stick to calling just the ``body()`` function.
+The caller can define any number of callables, allowing the
+``<%call>`` tag to produce whole layouts:
+
+.. sourcecode:: mako
+
+    <%def name="layout()">
+        ## a layout def
+        <div class="mainlayout">
+            <div class="header">
+                ${caller.header()}
+            </div>
+            <div class="sidebar">
+                ${caller.sidebar()}
+            </div>
+            <div class="content">
+                ${caller.body()}
+            </div>
+        </div>
+    </%def>
+
+    ## calls the layout def
+    <%self:layout>
+        <%def name="header()">
+            I am the header
+        </%def>
+        <%def name="sidebar()">
+            <ul>
+                <li>sidebar 1</li>
+                <li>sidebar 2</li>
+            </ul>
+        </%def>
+        
+            this is the body
+    </%self:layout>
+    
+The above layout would produce:
+
+.. sourcecode:: html
+
+    <div class="mainlayout">
+       <div class="header">
+       I am the header
+       </div>
+
+       <div class="sidebar">
+       <ul>
+           <li>sidebar 1</li>
+           <li>sidebar 2</li>
+       </ul>
+       </div>
+
+       <div class="content">
+       this is the body
+       </div>
+    </div>
+
+The number of things you can do with ``<%call>`` and/or the
+``<%namespacename:defname>`` calling syntax is enormous. You can
+create form widget libraries, such as an enclosing ``<FORM>``
+tag and nested HTML input elements, or portable wrapping schemes
+using ``<div>`` or other elements. You can create tags that
+interpret rows of data, such as from a database, providing the
+individual columns of each row to a ``body()`` callable which
+lays out the row any way it wants. Basically anything you'd do
+with a "custom tag" or tag library in some other system, Mako
+provides via ``<%def>`` tags and plain Python callables which are
+invoked via ``<%namespacename:defname>`` or ``<%call>``.
+
+
+
diff --git a/lib3/mako-0.3.6/doc/build/filtering.rst b/lib3/mako-0.3.6/doc/build/filtering.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/filtering.rst
@@ -0,0 +1,340 @@
+.. _filtering_toplevel:
+
+=======================
+Filtering and Buffering
+=======================
+
+Expression Filtering
+=====================
+
+As described in the chapter :ref:`syntax_toplevel`, the "``|``" operator can be
+applied to a "``${}``" expression to apply escape filters to the
+output:
+
+.. sourcecode:: mako
+
+    ${"this is some text" | u}
+
+The above expression applies URL escaping to the expression, and
+produces ``this+is+some+text``.
+
+The built-in escape flags are:
+
+* ``u`` : URL escaping, provided by
+  ``urllib.quote_plus(string.encode('utf-8'))``
+* ``h`` : HTML escaping, provided by
+  ``markupsafe.escape(string)`` (new as of 0.3.4 - prior
+  versions use ``cgi.escape(string, True)``)
+* ``x`` : XML escaping
+* ``trim`` : whitespace trimming, provided by ``string.strip()``
+* ``entity`` : produces HTML entity references for applicable
+  strings, derived from ``htmlentitydefs``
+* ``unicode`` (``str`` on Python 3): produces a Python unicode
+  string (this function is applied by default).
+* ``decode.<some encoding>`` : decode input into a Python
+  unicode with the specified encoding
+* ``n`` : disable all default filtering; only filters specified
+  in the local expression tag will be applied.
+
+To apply more than one filter, separate them by a comma:
+
+.. sourcecode:: mako
+
+    ${" <tag>some value</tag> " | h,trim}
+
+The above produces ``<tag>some value</tag>``, with
+no leading or trailing whitespace. The HTML escaping function is
+applied first, the "trim" function second.
+
+Naturally, you can make your own filters too. A filter is just a
+Python function that accepts a single string argument, and
+returns the filtered result. The expressions after the ``|``
+operator draw upon the local namespace of the template in which
+they appear, meaning you can define escaping functions locally:
+    
+.. sourcecode:: mako
+
+    <%!
+        def myescape(text):
+            return "<TAG>" + text + "</TAG>"
+    %>
+    
+    Heres some tagged text: ${"text" | myescape}
+    
+Or from any Python module:
+
+.. sourcecode:: mako
+
+    <%!
+        import myfilters
+    %>
+    
+    Heres some tagged text: ${"text" | myfilters.tagfilter}
+    
+A page can apply a default set of filters to all expression tags
+using the ``expression_filter`` argument to the ``%page`` tag:
+
+.. sourcecode:: mako
+
+    <%page expression_filter="h"/>
+    
+    Escaped text:  ${"<html>some html</html>"}
+    
+Result:
+
+.. sourcecode:: html
+
+    Escaped text: <html>some html</html>
+
+.. _filtering_default_filters:
+
+The default_filters Argument 
+----------------------------
+
+In addition to the ``expression_filter`` argument, the
+``default_filters`` argument to both ``Template`` and
+``TemplateLookup`` can specify filtering for all expression tags
+at the programmatic level. This array-based argument, when given
+its default argument of ``None``, will be internally set to
+``["unicode"]`` (or ``["str"]`` on Python 3), except when
+``disable_unicode=True`` is set in which case it defaults to
+``["str"]``:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], default_filters=['unicode'])
+
+To replace the usual ``unicode``/``str`` function with a
+specific encoding, the ``decode`` filter can be substituted:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], default_filters=['decode.utf8'])
+
+To disable ``default_filters`` entirely, set it to an empty
+list:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], default_filters=[])
+    
+Any string name can be added to ``default_filters`` where it
+will be added to all expressions as a filter. The filters are
+applied from left to right, meaning the leftmost filter is
+applied first.
+
+.. sourcecode:: python
+
+    t = Template(templatetext, default_filters=['unicode', 'myfilter'])
+    
+To ease the usage of ``default_filters`` with custom filters,
+you can also add imports (or other code) to all templates using
+the ``imports`` argument:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['/tmp'], 
+        default_filters=['unicode', 'myfilter'], 
+        imports=['from mypackage import myfilter'])
+    
+The above will generate templates something like this:
+
+.. sourcecode:: python
+
+    # ....
+    from mypackage import myfilter
+
+    def render_body(context):
+        context.write(myfilter(unicode("some text")))
+
+Turning off Filtering with the "n" filter
+------------------------------------------
+
+In all cases the special ``n`` filter, used locally within an
+expression, will **disable** all filters declared in the
+``<%page>`` tag as well ``default_filters``. Such as:
+
+.. sourcecode:: mako
+
+    ${'myexpression' | n}
+
+Will render ``myexpression`` with no filtering of any kind, and
+
+.. sourcecode:: mako
+
+    ${'myexpression' | n, trim}
+    
+will render ``myexpression`` using the ``trim`` filter only.  
+
+Filtering Defs
+=================
+
+The ``%def`` tag has a filter argument which will apply the
+given list of filter functions to the output of the ``%def``:
+
+.. sourcecode:: mako
+
+    <%def name="foo()" filter="h, trim">
+        <b>this is bold</b>
+    </%def>
+    
+When the filter attribute is applied to a def as above, the def
+is automatically **buffered** as well. This is described next.
+
+Buffering
+==========
+
+One of Mako's central design goals is speed. To this end, all of
+the textual content within a template and its various callables
+is by default piped directly to the single buffer that is stored
+within the ``Context`` object. While this normally is easy to
+miss, it has certain side effects. The main one is that when you
+call a def using the normal expression syntax, i.e.
+``${somedef()}``, it may appear that the return value of the
+function is the content it produced, which is then delivered to
+your template just like any other expression substitution,
+except that normally, this is not the case; the return value of
+``${somedef()}`` is simply the empty string ``''``. By the time
+you receive this empty string, the output of ``somedef()`` has
+been sent to the underlying buffer.
+
+You may not want this effect, if for example you are doing
+something like this:
+
+.. sourcecode:: mako
+
+    ${" results " + somedef() + " more results "}
+    
+If the ``somedef()`` function produced the content "``somedef's
+results``", the above template would produce this output:
+
+.. sourcecode:: html
+
+    somedef's results results more results
+    
+This is because ``somedef()`` fully executes before the
+expression returns the results of its concatenation; the
+concatenation in turn receives just the empty string as its
+middle expression.
+
+Mako provides two ways to work around this. One is by applying
+buffering to the ``%def`` itself:
+
+.. sourcecode:: mako
+
+    <%def name="somedef()" buffered="True">
+        somedef's results
+    </%def>
+    
+The above definition will generate code similar to this:
+
+.. sourcecode:: python
+
+    def somedef():
+        context.push_buffer()
+        try:
+            context.write("somedef's results")
+        finally:
+            buf = context.pop_buffer()
+        return buf.getvalue()
+        
+So that the content of ``somedef()`` is sent to a second buffer,
+which is then popped off the stack and its value returned. The
+speed hit inherent in buffering the output of a def is also
+apparent.
+
+Note that the ``filter`` argument on %def also causes the def to
+be buffered. This is so that the final content of the %def can
+be delivered to the escaping function in one batch, which
+reduces method calls and also produces more deterministic
+behavior for the filtering function itself, which can possibly
+be useful for a filtering function that wishes to apply a
+transformation to the text as a whole.
+
+The other way to buffer the output of a def or any Mako callable
+is by using the built-in ``capture`` function. This function
+performs an operation similar to the above buffering operation
+except it is specified by the caller.
+
+.. sourcecode:: mako
+
+    ${" results " + capture(somedef) + " more results "}
+    
+Note that the first argument to the ``capture`` function is
+**the function itself**, not the result of calling it. This is
+because the ``capture`` function takes over the job of actually
+calling the target function, after setting up a buffered
+environment. To send arguments to the function, just send them
+to ``capture`` instead:
+
+.. sourcecode:: mako
+
+    ${capture(somedef, 17, 'hi', use_paging=True)}
+    
+The above call is equivalent to the unbuffered call:
+
+.. sourcecode:: mako
+
+    ${somedef(17, 'hi', use_paging=True)}
+    
+Decorating
+===========
+
+This is a feature that's new as of version 0.2.5. Somewhat like
+a filter for a %def but more flexible, the ``decorator``
+argument to ``%def`` allows the creation of a function that will
+work in a similar manner to a Python decorator. The function can
+control whether or not the function executes. The original
+intent of this function is to allow the creation of custom cache
+logic, but there may be other uses as well.
+
+``decorator`` is intended to be used with a regular Python
+function, such as one defined in a library module. Here we'll
+illustrate the python function defined in the template for
+simplicities' sake:
+
+.. sourcecode:: mako
+
+    <%!
+        def bar(fn):
+            def decorate(context, *args, **kw):
+                context.write("BAR")
+                fn(*args, **kw)
+                context.write("BAR")
+                return ''
+            return decorate
+    %>
+    
+    <%def name="foo()" decorator="bar">
+        this is foo
+    </%def>
+    
+    ${foo()}
+    
+The above template will return, with more whitespace than this,
+``"BAR this is foo BAR"``. The function is the render callable
+itself (or possibly a wrapper around it), and by default will
+write to the context. To capture its output, use the ``capture``
+callable in the ``mako.runtime`` module (available in templates
+as just ``runtime``):
+
+.. sourcecode:: mako
+
+    <%!
+        def bar(fn):
+            def decorate(context, *args, **kw):
+                return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR"
+            return decorate
+    %>
+
+    <%def name="foo()" decorator="bar">
+        this is foo
+    </%def>
+
+    ${foo()}
+
+The decorator can be used with top-level defs as well as nested
+defs. Note that when calling a top-level def from the
+``Template`` api, i.e. ``template.get_def('somedef').render()``,
+the decorator has to write the output to the ``context``, i.e.
+as in the first example. The return value gets discarded.
diff --git a/lib3/mako-0.3.6/doc/build/index.rst b/lib3/mako-0.3.6/doc/build/index.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/index.rst
@@ -0,0 +1,21 @@
+Table of Contents
+=================
+
+.. toctree::
+    :maxdepth: 2
+    
+    usage
+    syntax
+    defs
+    runtime
+    namespaces
+    inheritance
+    filtering
+    unicode
+    caching
+    
+Indices and tables
+------------------
+
+* :ref:`genindex`
+* :ref:`search`
diff --git a/lib3/mako-0.3.6/doc/build/inheritance.rst b/lib3/mako-0.3.6/doc/build/inheritance.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/inheritance.rst
@@ -0,0 +1,321 @@
+.. _inheritance_toplevel:
+
+===========
+Inheritance
+===========
+
+Using template inheritance, two or more templates can organize
+themselves into an **inheritance chain**, where content and
+functions from all involved templates can be intermixed. The
+general paradigm of template inheritance is this: if a template
+``A`` inherits from template ``B``, then template ``A`` agrees
+to send the executional control to template ``B`` at runtime
+(``A`` is called the **inheriting** template). Template ``B``,
+the **inherited** template, then makes decisions as to what
+resources from ``A`` shall be executed.
+
+In practice, it looks like this. Heres a hypothetical inheriting
+template, ``index.html``:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="base.html"/>
+    
+    <%def name="header()">
+        this is some header content
+    </%def>
+    
+    this is the body content.
+    
+And ``base.html``, the inherited template:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                ${self.header()}
+            </div>
+            
+            ${self.body()}
+            
+            <div class="footer">
+                ${self.footer()}
+            </div>
+        </body>
+    </html>
+
+    <%def name="footer()">
+        this is the footer
+    </%def>
+
+Here is a breakdown of the execution:
+    
+* When ``index.html`` is rendered, control immediately passes to
+  ``base.html``.
+* ``base.html`` then renders the top part of an HTML document,
+  then calls the method ``header()`` off of a built in namespace
+  called ``self`` (this namespace was first introduced in the
+  Namespaces chapter in
+  :ref:`namespace_self`). Since
+  ``index.html`` is the topmost template and also defines a def
+  called ``header()``, its this ``header()`` def that gets
+  executed.
+* Control comes back to ``base.html``. Some more HTML is
+  rendered.
+* ``base.html`` executes ``self.body()``. The ``body()``
+  function on all template-based namespaces refers to the main
+  body of the template, therefore the main body of
+  ``index.html`` is rendered.
+* Control comes back to ``base.html``. More HTML is rendered,
+  then the ``self.footer()`` expression is invoked.
+* The ``footer`` def is only defined in ``base.html``, so being
+  the topmost definition of ``footer``, its the one that
+  executes. If ``index.html`` also specified ``footer``, then
+  its version would **override** that of the base.
+* ``base.html`` finishes up rendering its HTML and the template
+  is complete, producing:
+
+.. sourcecode:: html
+
+        <html>
+            <body>
+                <div class="header">
+                    this is some header content
+                </div>
+        
+                this is the body content.
+            
+                <div class="footer">
+                    this is the footer
+                </div>
+            </body>
+        </html>
+
+...and that is template inheritance in a nutshell. The main idea
+is that the methods that you call upon ``self`` always
+correspond to the topmost definition of that method. Very much
+the way ``self`` works in a Python class, even though Mako is
+not actually using Python class inheritance to implement this
+functionality. (Mako doesn't take the "inheritance" metaphor too
+seriously; while useful to setup some commonly recognized
+semantics, a textual template is not very much like an
+object-oriented class construct in practice).
+
+Using the "next" namespace to produce content wrapping 
+=======================================================
+
+Sometimes you have an inheritance chain that spans more than two
+templates. Or maybe you don't, but youd like to build your
+system such that extra inherited templates can be inserted in
+the middle of a chain where they would be smoothly integrated.
+If each template wants to define its layout just within its main
+body, you can't just call ``self.body()`` to get at the
+inheriting template's body, since that is only the topmost body.
+To get at the body of the *next* template, you call upon the
+namespace ``next``, which is the namespace of the template
+**immediately following** the current template.
+
+Lets change the line in ``base.html`` which calls upon
+``self.body()`` to instead call upon ``next.body()``:
+
+.. sourcecode:: mako
+
+    ## base.html
+    <html>
+        <body>
+            <div class="header">
+                ${self.header()}
+            </div>
+        
+            ${next.body()}
+        
+            <div class="footer">
+                ${self.footer()}
+            </div>
+        </body>
+    </html>
+
+    <%def name="footer()">
+        this is the footer
+    </%def>
+
+Lets also add an intermediate template called ``layout.html``,
+which inherits from ``base.html``:
+
+.. sourcecode:: mako
+
+    ## layout.html
+    <%inherit file="base.html"/>
+    <ul>
+        ${self.toolbar()}
+    </ul>
+    <div class="mainlayout">
+        ${next.body()}
+    </div>
+    
+    <%def name="toolbar()">
+        <li>selection 1</li>
+        <li>selection 2</li>
+        <li>selection 3</li>
+    </%def>    
+
+And finally change ``index.html`` to inherit from
+``layout.html`` instead:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="layout.html"/>
+    
+    ## .. rest of template
+    
+In this setup, each call to ``next.body()`` will render the body
+of the next template in the inheritance chain (which can be
+written as ``base.html -> layout.html -> index.html``). Control
+is still first passed to the bottommost template ``base.html``,
+and ``self`` still references the topmost definition of any
+particular def.
+
+The output we get would be:
+
+.. sourcecode:: html
+
+    <html>
+        <body>
+            <div class="header">
+                this is some header content
+            </div>
+
+            <ul>
+                <li>selection 1</li>
+                <li>selection 2</li>
+                <li>selection 3</li>
+            </ul>
+            
+            <div class="mainlayout">
+            this is the body content.
+            </div>
+            
+            <div class="footer">
+                this is the footer
+            </div>
+        </body>
+    </html>
+
+So above, we have the ``<html>``, ``<body>`` and
+``header``/``footer`` layout of ``base.html``, we have the
+``<ul>`` and ``mainlayout`` section of ``layout.html``, and the
+main body of ``index.html`` as well as its overridden ``header``
+def. The ``layout.html`` template is inserted into the middle of
+the chain without ``base.html`` having to change anything.
+Without the ``next`` namespace, only the main body of
+``index.html`` could be used; there would be no way to call
+``layout.html``'s body content.
+
+Using the "parent" namespace to augment defs 
+=============================================
+
+Lets now look at the other inheritance-specific namespace, the
+opposite of ``next`` called ``parent``. ``parent`` is the
+namespace of the template **immediately preceding** the current
+template. What is most useful about this namespace is the
+methods within it which can be accessed within overridden
+versions of those methods. This is not as hard as it sounds and
+is very much like using the ``super`` keyword in Python. Lets
+modify ``index.html`` to augment the list of selections provided
+by the ``toolbar`` function in ``layout.html``:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%inherit file="layout.html"/>
+
+    <%def name="header()">
+        this is some header content
+    </%def>
+
+    <%def name="toolbar()">
+        ## call the parent's toolbar first
+        ${parent.toolbar()}
+        <li>selection 4</li>
+        <li>selection 5</li>
+    </%def>
+        
+    this is the body content.
+
+Above, we implemented a ``toolbar()`` function, which is meant
+to override the definition of ``toolbar`` within the inherited
+template ``layout.html``. However, since we want the content
+from that of ``layout.html`` as well, we call it via the
+``parent`` namespace whenever we want it's content, in this case
+before we add our own selections. So the output for the whole
+thing is now:
+
+.. sourcecode:: html
+
+    <html>
+        <body>
+            <div class="header">
+                this is some header content
+            </div>
+
+            <ul>
+                <li>selection 1</li>
+                <li>selection 2</li>
+                <li>selection 3</li>
+                <li>selection 4</li>
+                <li>selection 5</li>
+            </ul>
+        
+            <div class="mainlayout">
+            this is the body content.
+            </div>
+        
+            <div class="footer">
+                this is the footer
+            </div>
+        </body>
+    </html>
+
+and you're now a template inheritance ninja !
+
+Inheritable Attributes
+======================
+
+The ``attr`` accessor of the :class:`.Namespace` object allows access
+to module level variables declared in a template. By accessing
+``self.attr``, you can access regular attributes from the
+inheritance chain as declared in ``<%! %>`` sections. Such as:
+
+.. sourcecode:: mako
+
+    <%!
+        class_ = "grey"
+    %>
+    
+    <div class="${self.attr.class_}">
+        ${self.body()}
+    </div>
+    
+If a an inheriting template overrides ``class_`` to be
+``white``, as in:
+
+.. sourcecode:: mako
+
+    <%!
+        class_ = "white"
+    %>
+    <%inherit file="parent.html"/>
+    
+    This is the body
+    
+You'll get output like:
+
+.. sourcecode:: html
+
+    <div class="white">
+        This is the body
+    </div>
diff --git a/lib3/mako-0.3.6/doc/build/namespaces.rst b/lib3/mako-0.3.6/doc/build/namespaces.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/namespaces.rst
@@ -0,0 +1,341 @@
+.. _namespaces_toplevel:
+
+==========
+Namespaces
+==========
+
+Namespaces are used to organize groups of components into
+categories, and also to "import" components from other files.
+
+If the file ``components.html`` defines these two components:
+
+.. sourcecode:: mako
+
+    ## components.html
+    <%def name="comp1()">
+        this is comp1
+    </%def>
+    
+    <%def name="comp2(x)">
+        this is comp2, x is ${x}
+    </%def>
+    
+You can make another file, for example ``index.html``, that
+pulls those two components into a namespace called ``comp``:
+
+.. sourcecode:: mako
+
+    ## index.html
+    <%namespace name="comp" file="components.html"/>
+    
+    Heres comp1:  ${comp.comp1()}
+    Heres comp2:  ${comp.comp2(x=5)}
+
+The ``comp`` variable above is an instance of
+:class:`.Namespace`, a **proxy object** which delivers
+method calls to the underlying template callable using the
+current context.
+
+``<%namespace>`` also provides an ``import`` attribute which can
+be used to pull the names into the local namespace, removing the
+need to call it via the ".". When ``import`` is used, the
+``name`` attribute is optional.
+
+.. sourcecode:: mako
+
+    <%namespace file="components.html" import="comp1, comp2"/>
+    
+    Heres comp1:  ${comp1()}
+    Heres comp2:  ${comp2(x=5)}
+    
+``import`` also supports the "*" operator:
+
+.. sourcecode:: mako
+
+    <%namespace file="components.html" import="*"/>
+
+    Heres comp1:  ${comp1()}
+    Heres comp2:  ${comp2(x=5)}
+
+The names imported by the ``import`` attribute take precedence
+over any names that exist within the current context.
+
+.. note:: in current versions of Mako, usage of ``import='*'`` is
+   known to decrease performance of the template. This will be
+   fixed in a future release.
+
+The ``file`` argument allows expressions - if looking for
+context variables, the ``context`` must be named explicitly:
+
+.. sourcecode:: mako
+
+    <%namespace name="dyn" file="${context['namespace_name']}"/>
+    
+Ways to Call Namespaces
+========================
+
+There are essentially four ways to call a function from a
+namespace.
+
+The "expression" format, as described previously. Namespaces are
+just Python objects with functions on them, and can be used in
+expressions like any other function:
+
+.. sourcecode:: mako
+
+    ${mynamespace.somefunction('some arg1', 'some arg2', arg3='some arg3', arg4='some arg4')}
+    
+Synonymous with the "expression" format is the "custom tag"
+format, when a "closed" tag is used. This format, introduced in
+Mako 0.2.3, allows the usage of a "custom" Mako tag, with the
+function arguments passed in using named attributes:
+
+.. sourcecode:: mako
+
+    <%mynamespace:somefunction arg1="some arg1" arg2="some arg2" arg3="some arg3" arg4="some arg4"/>
+    
+When using tags, the values of the arguments are taken as
+literal strings by default. To embed Python expressions as
+arguments, use the embedded expression format:
+
+.. sourcecode:: mako
+
+    <%mynamespace:somefunction arg1="${someobject.format()}" arg2="${somedef(5, 12)}"/>
+
+The "custom tag" format is intended mainly for namespace
+functions which recognize body content, which in Mako is known
+as a "def with embedded content":
+
+.. sourcecode:: mako
+
+    <%mynamespace:somefunction arg1="some argument" args="x, y">
+        Some record: ${x}, ${y}
+    </%mynamespace:somefunction>
+
+The "classic" way to call defs with embedded content is the ``<%call>`` tag:
+
+.. sourcecode:: mako
+
+    <%call expr="mynamespace.somefunction(arg1='some argument')" args="x, y">
+        Some record: ${x}, ${y}
+    </%call>
+
+For information on how to construct defs that embed content from
+the caller, see :ref:`defs_with_content`.
+
+.. _namespaces_python_modules:
+
+Namespaces from Regular Python Modules 
+========================================
+
+Namespaces can also import regular Python functions from
+modules. These callables need to take at least one argument,
+``context``, an instance of :class:`.Context`. A module file 
+``some/module.py`` might contain the callable:
+
+.. sourcecode:: python
+
+    def my_tag(context):
+        context.write("hello world")
+        return ''
+
+A template can use this module via:
+    
+.. sourcecode:: mako
+
+    <%namespace name="hw" module="some.module"/>
+
+    ${hw.my_tag()}
+    
+Note that the ``context`` argument is not needed in the call;
+the :class:`.Namespace` tag creates a locally-scoped callable which
+takes care of it. The ``return ''`` is so that the def does not
+dump a ``None`` into the output stream - the return value of any
+def is rendered after the def completes, in addition to whatever
+was passed to :meth:`.Context.write` within its body.
+
+If your def is to be called in an "embedded content" context,
+that is as described in :ref:`defs_with_content`, you should use
+the :func:`.supports_caller` decorator, which will ensure that Mako
+will ensure the correct "caller" variable is available when your
+def is called, supporting embedded content:
+
+.. sourcecode:: python
+
+    from mako.runtime import supports_caller
+    
+    @supports_caller
+    def my_tag(context):
+        context.write("<div>")
+        context['caller'].body()
+        context.write("</div>")
+        return ''
+        
+Capturing of output is available as well, using the
+outside-of-templates version of the :func:`.capture` function,
+which accepts the "context" as its first argument:
+
+.. sourcecode:: python
+
+    from mako.runtime import supports_caller, capture
+
+    @supports_caller
+    def my_tag(context):
+        return "<div>%s</div>" % \
+                capture(context, context['caller'].body, x="foo", y="bar")
+
+Declaring defs in namespaces
+=============================
+
+The ``<%namespace>`` tag supports the definition of ``<%defs>``
+directly inside the tag. These defs become part of the namespace
+like any other function, and will override the definitions
+pulled in from a remote template or module:
+    
+.. sourcecode:: mako
+
+    ## define a namespace
+    <%namespace name="stuff">
+        <%def name="comp1()">
+            comp1
+        </%def>
+    </%namespace>
+    
+    ## then call it
+    ${stuff.comp1()}
+
+.. _namespaces_body:
+
+The "body()" method 
+=====================
+
+Every namespace that is generated from a template contains a
+method called ``body()``. This method corresponds to the main
+body of the template, and plays its most important roles when
+using inheritance relationships as well as
+def-calls-with-content.
+
+Since the ``body()`` method is available from a namespace just
+like all the other defs defined in a template, what happens if
+you send arguments to it ? By default, the ``body()`` method
+accepts no positional arguments, and for usefulness in
+inheritance scenarios will by default dump all keyword arguments
+into a dictionary called ``pageargs``. But if you actually want
+to get at the keyword arguments, Mako recommends you define your
+own argument signature explicitly. You do this via using the
+``<%page>`` tag:
+
+.. sourcecode:: mako
+
+    <%page args="x, y, someval=8, scope='foo', **kwargs"/>
+    
+A template which defines the above signature requires that the
+variables ``x`` and ``y`` are defined, defines default values
+for ``someval`` and ``scope``, and sets up ``**kwargs`` to
+receive all other keyword arguments. If ``**kwargs`` or similar
+is not present, the argument ``**pageargs`` gets tacked on by
+Mako. When the template is called as a top-level template (i.e.
+via :meth:`~.Template.render`) or via the ``<%include>`` tag, the
+values for these arguments will be pulled from the ``Context``.
+In all other cases, i.e. via calling the ``body()`` method, the
+arguments are taken as ordinary arguments from the method call.
+So above, the body might be called as:
+
+.. sourcecode:: mako
+
+    ${self.body(5, y=10, someval=15, delta=7)}
+    
+The :class:`.Context` object also supplies a :attr:`~.Context.kwargs` accessor, for
+cases when youd like to pass along whatever is in the context to
+a ``body()`` callable:
+
+.. sourcecode:: mako
+
+    ${next.body(**context.kwargs)}
+
+The usefulness of calls like the above become more apparent when
+one works with inheriting templates. For more information on
+this, as well as the meanings of the names ``self`` and
+``next``, see :ref:`inheritance_toplevel`.
+
+.. _namespaces_builtin:
+
+Built-in Namespaces 
+====================
+
+The namespace is so great that Mako gives your template one (or
+two) for free. The names of these namespaces are ``local`` and
+``self``. Other built-in namespaces include ``parent`` and
+``next``, which are optional and are described in
+:ref:`inheritance_toplevel`.
+
+.. _namespace_local:
+
+local
+-----
+
+The ``local`` namespace is basically the namespace for the
+currently executing template. This means that all of the top
+level defs defined in your template, as well as your template's
+``body()`` function, are also available off of the ``local``
+namespace.
+
+The ``local`` namespace is also where properties like ``uri``,
+``filename``, and ``module`` and the ``get_namespace`` method
+can be particularly useful.
+
+.. _namespace_self:
+
+self
+-----
+
+The ``self`` namespace, in the case of a template that does not
+use inheritance, is synonomous with ``local``. If inheritance is
+used, then ``self`` references the topmost template in the
+inheritance chain, where it is most useful for providing the
+ultimate form of various "method" calls which may have been
+overridden at various points in an inheritance chain. See
+:ref:`inheritance_toplevel`.
+
+Inheritable Namespaces
+========================
+
+The ``<%namespace>`` tag includes an optional attribute
+``inheritable="True"``, which will cause the namespace to be
+attached to the ``self`` namespace. Since ``self`` is globally
+available throughout an inheritance chain (described in the next
+section), all the templates in an inheritance chain can get at
+the namespace imported in a super-template via ``self``.
+    
+.. sourcecode:: mako
+
+    ## base.html
+    <%namespace name="foo" file="foo.html" inheritable="True"/>
+    
+    ${next.body()}
+
+    ## somefile.html
+    <%inherit file="base.html"/>
+    
+    ${self.foo.bar()}
+
+This allows a super-template to load a whole bunch of namespaces
+that its inheriting templates can get to, without them having to
+explicitly load those namespaces themselves.
+
+The ``import="*"`` part of the ``<%namespace>`` tag doesn't yet
+interact with the ``inheritable`` flag, so currently you have to
+use the explicit namespace name off of ``self``, followed by the
+desired function name. But more on this in a future release.
+
+API Reference
+==============
+
+.. autoclass:: mako.runtime.Namespace
+    :show-inheritance:
+    :members:
+    
+.. autofunction:: mako.runtime.supports_caller
+
+.. autofunction:: mako.runtime.capture
+
diff --git a/lib3/mako-0.3.6/doc/build/runtime.rst b/lib3/mako-0.3.6/doc/build/runtime.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/runtime.rst
@@ -0,0 +1,238 @@
+.. _runtime_toplevel:
+
+=============================
+The Mako Runtime Environment 
+=============================
+
+This section describes a little bit about the objects and
+built-in functions that are available in templates.
+
+Context
+=======
+
+The :class:`.Context` is the central object that is created when
+a template is first executed, and is responsible for handling
+all communication with the outside world. This includes two
+major components, one of which is the output buffer, which is a
+file-like object such as Python's ``StringIO`` or similar, and
+the other a dictionary of variables that can be freely
+referenced within a template; this dictionary is a combination
+of the arguments sent to the :meth:`~.Template.render` function and
+some built-in variables provided by Mako's runtime environment.
+
+The Buffer
+----------
+
+The buffer is stored within the :class:`.Context`, and writing
+to it is achieved by calling :meth:`.Context.write`. You usually
+don't need to care about this as all text within a template, as
+well as all expressions provided by ``${}``, automatically send
+everything to this method. The cases you might want to be aware
+of its existence are if you are dealing with various
+filtering/buffering scenarios, which are described in
+:ref:`filtering_toplevel`, or if you want to programmatically
+send content to the output stream, such as within a ``<% %>``
+block.
+
+.. sourcecode:: mako
+
+    <%
+        context.write("some programmatic text")
+    %>
+
+The actual buffer may or may not be the original buffer sent to
+the :class:`.Context` object, as various filtering/caching
+scenarios may "push" a new buffer onto the context's underlying
+buffer stack. For this reason, just stick with
+:meth:`.Context.write` and content will always go to the topmost
+buffer.
+
+Context Variables
+------------------
+
+When your template is compiled into a Python module, the body
+content is enclosed within a Python function called
+``render_body``. Other top-level defs defined in the template are
+defined within their own function bodies which are named after
+the def's name with the prefix ``render_`` (i.e. ``render_mydef``).
+One of the first things that happens within these functions is
+that all variable names that are referenced within the function
+which are not defined in some other way (i.e. such as via
+assignment, module level imports, etc.) are pulled from the
+:class:`.Context` object's dictionary of variables. This is how you're
+able to freely reference variable names in a template which
+automatically correspond to what was passed into the current
+:class:`.Context`.
+
+* **What happens if I reference a variable name that is not in
+  the current context?** - the value you get back is a special
+  value called ``UNDEFINED``, or if the ``strict_undefined=True`` flag
+  is used a ``NameError`` is raised. ``UNDEFINED`` is just a simple global
+  variable with the class ``mako.runtime.Undefined``. The
+  ``UNDEFINED`` object throws an error when you call ``str()`` on
+  it, which is what happens if you try to use it in an
+  expression.
+* **UNDEFINED makes it hard for me to find what name is missing** - An alternative 
+  introduced in version 0.3.6 is to specify the option
+  ``strict_undefined=True``
+  to the :class:`.Template` or :class:`.TemplateLookup`.   This will cause
+  any non-present variables to raise an immediate ``NameError``
+  which includes the name of the variable in its message
+  when :meth:`~.Template.render` is called - ``UNDEFINED`` is not used.
+* **Why not just return None?** Using ``UNDEFINED``, or 
+  raising a ``NameError`` is more
+  explicit and allows differentiation between a value of ``None``
+  that was explicitly passed to the :class:`.Context` and a value that
+  wasn't present at all.
+* **Why raise an exception when you call str() on it ? Why not
+  just return a blank string?** - Mako tries to stick to the
+  Python philosophy of "explicit is better than implicit". In
+  this case, its decided that the template author should be made
+  to specifically handle a missing value rather than
+  experiencing what may be a silent failure. Since ``UNDEFINED``
+  is a singleton object just like Python's ``True`` or ``False``,
+  you can use the ``is`` operator to check for it:
+
+ .. sourcecode:: mako
+ 
+        % if someval is UNDEFINED:
+            someval is: no value
+        % else:
+            someval is: ${someval}
+        % endif
+        
+Another facet of the :class:`.Context` is that its dictionary of
+variables is **immutable**. Whatever is set when
+:meth:`~.Template.render` is called is what stays. Of course, since
+its Python, you can hack around this and change values in the
+context's internal dictionary, but this will probably will not
+work as well as you'd think. The reason for this is that Mako in
+many cases creates copies of the :class:`.Context` object, which
+get sent to various elements of the template and inheriting
+templates used in an execution. So changing the value in your
+local :class:`.Context` will not necessarily make that value
+available in other parts of the template's execution. Examples
+of where Mako creates copies of the :class:`.Context` include
+within top-level def calls from the main body of the template
+(the context is used to propagate locally assigned variables
+into the scope of defs; since in the template's body they appear
+as inlined functions, Mako tries to make them act that way), and
+within an inheritance chain (each template in an inheritance
+chain has a different notion of ``parent`` and ``next``, which
+are all stored in unique :class:`.Context` instances).
+
+* **So what if I want to set values that are global to everyone
+  within a template request?** - All you have to do is provide a
+  dictionary to your :class:`.Context` when the template first
+  runs, and everyone can just get/set variables from that. Lets
+  say its called ``attributes``.
+
+  Running the template looks like:
+
+  .. sourcecode:: python
+
+      output = template.render(attributes={})
+
+  Within a template, just reference the dictionary:
+
+  .. sourcecode:: mako
+
+      <%
+          attributes['foo'] = 'bar'
+      %>
+      'foo' attribute is: ${attributes['foo']}
+        
+* **Why can't "attributes" be a built-in feature of the
+  Context?** - This is an area where Mako is trying to make as
+  few decisions about your application as it possibly can.
+  Perhaps you don't want your templates to use this technique of
+  assigning and sharing data, or perhaps you have a different
+  notion of the names and kinds of data structures that should
+  be passed around. Once again Mako would rather ask the user to
+  be explicit.
+
+Context Methods and Accessors
+------------------------------
+
+Significant members off of :class:`.Context` include:
+
+* ``context[key]`` / ``context.get(key, default=None)`` -
+  dictionary-like accessors for the context. Normally, any
+  variable you use in your template is automatically pulled from
+  the context if it isnt defined somewhere already. Use the
+  dictionary accessor and/or ``get`` method when you want a
+  variable that *is* already defined somewhere else, such as in
+  the local arguments sent to a %def call. If a key is not
+  present, like a dictionary it raises ``KeyError``.
+* ``keys()`` - all the names defined within this context.
+* ``kwargs`` - this returns a **copy** of the context's
+  dictionary of variables. This is useful when you want to
+  propagate the variables in the current context to a function
+  as keyword arguments, i.e.:
+
+.. sourcecode:: mako
+
+        ${next.body(**context.kwargs)}
+
+* ``write(text)`` - write some text to the current output
+  stream.
+* ``lookup`` - returns the :class:`.TemplateLookup` instance that is
+  used for all file-lookups within the current execution (even
+  though individual :class:`.Template` instances can conceivably have
+  different instances of a :class:`.TemplateLookup`, only the
+  :class:`.TemplateLookup` of the originally-called :class:`.Template` gets
+  used in a particular execution).
+
+All the built-in names
+======================
+
+A one-stop shop for all the names Mako defines. Most of these
+names are instances of :class:`.Namespace`, which are described
+in the next section, :ref:`namespaces_toplevel`. Also, most of
+these names other than :class:`.Context` and ``UNDEFINED`` are
+also present *within* the :class:`.Context` itself.
+
+* ``local`` - the namespace of the current template, described
+  in :ref:`namespaces_builtin`.
+* ``self`` - the namespace of the topmost template in an
+  inheritance chain (if any, otherwise the same as ``local``),
+  mostly described in :ref:`inheritance_toplevel`.
+* ``parent`` - the namespace of the parent template in an
+  inheritance chain (otherwise undefined); see
+  :ref:`inheritance_toplevel`.
+* ``next`` - the namespace of the next template in an
+  inheritance chain (otherwise undefined); see
+  :ref:`inheritance_toplevel`.
+* ``caller`` - a "mini" namespace created when using the
+  ``<%call>`` tag to define a "def call with content"; described
+  in :ref:`defs_with_content`.
+* ``capture`` - a function that calls a given def and captures
+  its resulting content into a string, which is returned. Usage
+  is described in :ref:`filtering_toplevel`.
+* ``UNDEFINED`` - a global singleton that is applied to all
+  otherwise uninitialized template variables that were not
+  located within the :class:`.Context` when rendering began,
+  unless the :class:`.Template` flag ``strict_undefined`` 
+  is set to ``True``. ``UNDEFINED`` is
+  an instance of :class:`.Undefined`, and raises an
+  exception when its ``__str__()`` method is called.
+* ``pageargs`` - this is a dictionary which is present in a
+  template which does not define any \**kwargs section in its
+  ``<%page>`` tag. All keyword arguments sent to the ``body()``
+  function of a template (when used via namespaces) go here by
+  default unless otherwise defined as a page argument. If this
+  makes no sense, it shouldn't; read the section
+  :ref:`namespaces_body`.
+
+API Reference
+==============
+
+.. autoclass:: mako.runtime.Context
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.runtime.Undefined
+    :show-inheritance:
+    
+
+
diff --git a/lib3/mako-0.3.6/doc/build/static/docs.css b/lib3/mako-0.3.6/doc/build/static/docs.css
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/static/docs.css
@@ -0,0 +1,288 @@
+/* documentation section styles */
+
+body, td {
+	font-family: Tahoma,Geneva,sans-serif;
+}
+
+body {
+	background-color: #FDFBFC;
+	margin:38px;
+	color:#333333;
+}
+
+form {
+    display:inline;
+}
+
+p {
+	margin-top:10px;
+	margin-bottom:10px;
+}
+
+
+a {
+        font-weight:normal; 
+        text-decoration:none;
+}
+a:link {color:#0000FF;}
+a:visited {color:#0000FF;}
+a:active {color:#0000FF;}
+a:hover {color:#700000;}
+
+
+strong a {
+    font-weight: bold;
+}
+
+#search {
+    float:right;
+}
+
+#searchform {
+    padding:20px;
+}
+
+#pagecontrol {
+    float:right;
+}
+
+.topnav {
+	background-color: #eeeeee;
+	border: solid 1px #ccc;
+	padding:10px;
+	margin:10px 0px 10px 0px;
+}
+
+.bottomnav {
+	background-color: #eeeeee;
+    border:1px solid #CCCCCC;
+    float:right;
+    margin: 1em 0 1em 5px;
+    padding:10px;
+}
+
+.document {
+	border: solid 1px #ccc;
+}
+
+.topnav .prevnext {
+    padding: 5px 0px 0px 0px;
+    /*font-size: 0.8em*/
+}
+
+h1, h2, h3, h4, h5 {
+    font-weight:bold;
+}
+
+h1 {
+    font-size:1.6em;
+    font-weight:bold;
+}
+.document h1, .document h2, .document h3, .document h4, .document h5 {
+    font-size: 1.2em;
+}
+
+.document img {
+    display:block;
+    margin: 0 auto;
+}
+
+.document h1 {
+    display:none;
+}
+
+.topnav h2 {
+    margin:26px 4px 0px 5px;
+    font-size:1.6em;
+    font-weight:normal;
+    line-height:1.6em;  
+}
+
+.topnav h3 {
+    font-weight: bold;
+    font-size: 1.4em;
+    margin:0px;
+    display:inline;
+}
+
+.topnav li,
+li.toctree-l1,
+li.toctree-l1 li
+{
+    list-style-type:disc;
+    margin:0px;
+    padding:1px 8px;
+}
+
+
+.topnav li ul, 
+li.toctree-l1 ul
+{
+    padding:0px 0px 0px 20px;
+}
+
+.topnav li ul li li, 
+li.toctree-l1 ul li li
+{
+    /*font-size:.90em;*/
+}
+
+.sourcelink {
+    font-size:.8em;
+    text-align:right;
+    padding-top:10px;
+}
+
+.section {
+    line-height: 1.5em;
+    padding:8px 10px 20px 10px;
+    margin:10px 0px 0px;
+}
+
+.section .section {
+    margin:0px 0px 0px 0px;
+    padding: 0px;
+}
+
+.section .section .section {
+    margin:0px 0px 0px 20px;
+}
+
+.section .section .section .section {
+    margin:0px 0px 0px 20px;
+}
+
+th.field-name {
+    text-align:right;
+}
+
+div.note, div.warning, p.deprecated  {
+    background-color:#EEFFEF;
+}
+
+
+div.admonition, div.topic, p.deprecated {
+    border:1px solid #CCCCCC;
+    margin:5px 5px 5px 5px;
+    padding:5px 5px 5px 35px;
+    font-size:.9em;
+}
+
+div.warning .admonition-title {
+    color:#FF0000;
+}
+
+div.admonition .admonition-title {
+    font-weight:bold;
+}
+
+
+.totoc {
+    
+}
+
+.doc_copyright {
+    font-size:.85em;
+    padding:10px 0px 10px 0px;
+}
+
+pre {
+	background-color: #f0f0f0;	
+	border: solid 1px #ccc;
+	padding:10px;
+	margin: 5px 5px 5px 5px;
+	overflow:auto;
+	line-height:1.3em;
+}
+
+.versionheader {
+    margin-top: 0.5em;
+}
+.versionnum {
+    font-weight: bold;
+}
+
+.viewcode-back, .viewcode-link {
+    float:right;
+}
+.prerelease {
+    border: solid #c25757 2px;
+    border-radius: 4px;
+    -moz-border-radius: 4px;
+    -webkit-border-radius: 4px;
+    background-color: #c21a1a;
+    color: white;
+    padding: 0.05em 0.2em;
+}
+
+dl.function > dt,
+dl.attribute > dt,
+dl.classmethod > dt,
+dl.method > dt,
+dl.class > dt,
+dl.exception > dt
+{
+    background-color:#F0F0F0;
+    margin:0px -10px;
+    padding: 0px 10px;
+}
+
+
+dt:target, span.highlight {
+    background-color:#FBE54E;
+}
+
+a.headerlink {
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+a.headerlink:hover {
+    background-color: #00f;
+    color: white;
+}
+
+.clearboth {
+    clear:both;
+}
+
+tt.descname {
+    background-color:transparent;
+    font-size:1.2em;
+    font-weight:bold;
+}
+
+tt.descclassname {
+    background-color:transparent;
+}
+
+tt {
+    background-color:#ECF0F3;
+    padding:0 1px;
+}
+
+ at media print {
+  #nav { display: none; }
+  #pagecontrol { display: none; }
+  .topnav .prevnext { display: none; }
+  .bottomnav { display: none; }
+  .totoc { display: none; }
+  .topnav ul li a { text-decoration: none; color: #000; }
+}
+
+/* syntax highlighting overrides */
+.k, .kn {color:#0908CE;}
+.o {color:#BF0005;}
+.go {color:#804049;}
diff --git a/lib3/mako-0.3.6/doc/build/syntax.rst b/lib3/mako-0.3.6/doc/build/syntax.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/syntax.rst
@@ -0,0 +1,417 @@
+.. _syntax_toplevel:
+
+======
+Syntax
+======
+
+A Mako template is parsed from a text stream containing any kind
+of content, XML, HTML, email text, etc. The template can further
+contain Mako-specific directives which represent variable and/or
+expression substitutions, control structures (i.e. conditionals
+and loops), server-side comments, full blocks of Python code, as
+well as various tags that offer additional functionality. All of
+these constructs compile into real Python code. This means that
+you can leverage the full power of Python in almost every aspect
+of a Mako template.
+
+Expression Substitution
+========================
+
+The simplest expression is just a variable substitution. The
+syntax for this is the ``${}`` construct, which is inspired by
+Perl, Genshi, JSP EL, and others:
+
+.. sourcecode:: mako
+
+    this is x: ${x}
+
+Above, the string representation of ``x`` is applied to the
+template's output stream. If you're wondering where ``x`` comes
+from, its usually from the ``Context`` supplied to the
+template's rendering function. If ``x`` was not supplied to the
+template and was not otherwise assigned locally, it evaluates to
+a special value ``UNDEFINED``. More on that later.
+    
+The contents within the ``${}`` tag are evaluated by Python
+directly, so full expressions are OK:
+
+.. sourcecode:: mako
+
+    pythagorean theorem:  ${pow(x,2) + pow(y,2)}
+    
+The results of the expression are evaluated into a string result
+in all cases before being rendered to the output stream, such as
+the above example where the expression produces a numeric
+result.
+
+Expression Escaping
+===================
+
+
+Mako includes a number of built-in escaping mechanisms,
+including HTML, URI and XML escaping, as well as a "trim"
+function. These escapes can be added to an expression
+substituion using the ``|`` operator:
+
+.. sourcecode:: mako
+
+    ${"this is some text" | u}
+
+The above expression applies URL escaping to the expression, and
+produces ``this+is+some+text``. The ``u`` name indicates URL
+escaping, whereas ``h`` represents HTML escaping, ``x``
+represents XML escaping, and ``trim`` applies a trim function.
+
+Read more about built in filtering functions, including how to
+make your own filter functions, in :ref:`filtering_toplevel`.
+
+Control Structures
+==================
+
+A control structure refers to all those things that control the
+flow of a program - conditionals (i.e. if/else), loops (like
+while and for), as well as things like ``try/except``. In Mako,
+control structures are written using the ``%`` marker followed
+by a regular Python control expression, and are "closed" by
+using another ``%`` marker with the tag "``end<name>``", where
+"``<name>``" is the keyword of the expression:
+
+.. sourcecode:: mako
+
+    % if x==5:
+        this is some output
+    % endif
+    
+The ``%`` can appear anywhere on the line as long as no text
+precedes it; indentation is not signficant. The full range of
+Python "colon" expressions are allowed here, including
+``if/elif/else``, ``while``, ``for``, and even ``def``, although
+Mako has a built-in tag for defs which is more full-featured.
+
+.. sourcecode:: mako
+
+    % for a in ['one', 'two', 'three', 'four', 'five']:
+        % if a[0] == 't':
+         its two or three
+        % elif a[0] == 'f':
+        four/five
+        % else:
+        one
+        %endif
+    % endfor
+
+The ``%`` sign can also be "escaped", if you actually want to
+emit a percent sign as the first non whitespace character on a
+line, by escaping it as in ``%%``:
+
+.. sourcecode:: mako
+
+    %% some text
+    
+        %% some more text
+
+Comments
+========
+
+Comments come in two varieties. The single line comment uses
+``##`` as the first non-space characters on a line:
+
+.. sourcecode:: mako
+
+    ## this is a comment.
+    ...text ...
+
+A multiline version exists using ``<%doc>  ...text... </%doc>``:
+
+.. sourcecode:: mako
+
+    <%doc>
+        these are comments
+        more comments
+    </%doc>
+
+Newline Filters
+================
+
+The backslash ("``\``") character, placed at the end of any
+line, will consume the newline character before continuing to
+the next line:
+
+.. sourcecode:: mako
+
+    here is a line that goes onto \
+    another line.
+    
+The above text evaluates to::
+
+    here is a line that goes onto another line.
+    
+Python Blocks
+=============
+
+Any arbitrary block of python can be dropped in using the ``<%
+%>`` tags:
+
+.. sourcecode:: mako
+
+    this is a template
+    <%
+        x = db.get_resource('foo')
+        y = [z.element for z in x if x.frobnizzle==5]
+    %>
+    % for elem in y:
+        element: ${elem}
+    % endfor
+    
+Within ``<% %>``, you're writing a regular block of Python code.
+While the code can appear with an arbitrary level of preceding
+whitespace, it has to be consistently formatted with itself.
+Mako's compiler will adjust the block of Python to be consistent
+with the surrounding generated Python code.
+
+Module-level Blocks
+====================
+
+A variant on ``<% %>`` is the module-level code block, denoted
+by ``<%! %>``. Code within these tags is executed at the module
+level of the template, and not within the rendering function of
+the template. Therefore, this code does not have access to the
+template's context and is only executed when the template is
+loaded into memory (which can be only once per application, or
+more, depending on the runtime environment). Use the ``<%! %>``
+tags to declare your template's imports, as well as any
+pure-Python functions you might want to declare:
+
+.. sourcecode:: mako
+
+    <%!
+        import mylib
+        import re
+        
+        def filter(text):
+            return re.sub(r'^@', '', text)
+    %>
+    
+Any number of ``<%! %>`` blocks can be declared anywhere in a
+template; they will be rendered in the resulting module 
+in a single contiguous block above all render callables,
+in the order in which they appear in the source template.
+
+Tags
+====
+
+The rest of what Mako offers takes place in the form of tags.
+All tags use the same syntax, which is similar to an XML tag
+except that the first character of the tag name is a ``%``
+character. The tag is closed either by a contained slash
+character, or an explicit closing tag:
+
+.. sourcecode:: mako
+
+    <%include file="foo.txt"/>
+    
+    <%def name="foo" buffered="True">
+        this is a def
+    </%def>
+    
+All tags have a set of attributes which are defined for each
+tag. Some of these attributes are required. Also, many
+attributes support **evaluation**, meaning you can embed an
+expression (using ``${}``) inside the attribute text:
+
+.. sourcecode:: mako
+
+    <%include file="/foo/bar/${myfile}.txt"/>
+    
+Whether or not an attribute accepts runtime evaluation depends
+on the type of tag and how that tag is compiled into the
+template. The best way to find out if you can stick an
+expression in is to try it ! The lexer will tell you if its not
+valid.
+
+Heres a quick summary of all the tags:
+
+<%page>
+-------
+
+This tag defines general characteristics of the template,
+including caching arguments, and optional lists of arguments
+which the template expects when invoked.
+
+.. sourcecode:: mako
+
+    <%page args="x, y, z='default'"/>
+    
+Or a page tag that defines caching characteristics:
+    
+.. sourcecode:: mako
+
+    <%page cached="True" cache_type="memory"/>
+
+Currently, only one ``<%page>`` tag gets used per template, the
+rest get ignored. While this will be improved in a future
+release, for now make sure you have only one ``<%page>`` tag
+defined in your template, else you may not get the results you
+want. The details of what ``<%page>`` is used for are described
+further in :ref:`namespaces_body` as well as :ref:`caching_toplevel`.
+    
+<%include>
+-----------
+
+A tag that is familiar from other template languages, %include
+is a regular joe that just accepts a file argument and calls in
+the rendered result of that file:
+
+.. sourcecode:: mako
+
+    <%include file="header.html"/>
+    
+        hello world
+        
+    <%include file="footer.html"/>
+
+Include also accepts arguments which are available as ``<%page>`` arguments in the receiving template:
+
+.. sourcecode:: mako
+
+    <%include file="toolbar.html" args="current_section='members', username='ed'"/>
+
+<%def>
+------
+
+The ``%def`` tag defines a Python function which contains a set
+of content, that can be called at some other point in the
+template. The basic idea is simple:
+
+.. sourcecode:: mako
+
+    <%def name="myfunc(x)">
+        this is myfunc, x is ${x}
+    </%def>
+    
+    ${myfunc(7)}
+    
+The %def tag is a lot more powerful than a plain Python def, as
+the Mako compiler provides many extra services with %def that
+you wouldn't normally have, such as the ability to export defs
+as template "methods", automatic propagation of the current
+``Context``, buffering/filtering/caching flags, and def calls
+with content, which enable packages of defs to be sent as
+arguments to other def calls (not as hard as it sounds). Get the
+full deal on what %def can do in :ref:`defs_toplevel`.
+
+<%namespace>
+-------------
+
+%namespace is Mako's equivalent of Python's ``import``
+statement. It allows access to all the rendering functions and
+metadata of other template files, plain Python modules, as well
+as locally defined "packages" of functions.
+
+.. sourcecode:: mako
+
+    <%namespace file="functions.html" import="*"/>
+
+The underlying object generated by %namespace, an instance of
+:class:`.mako.runtime.Namespace`, is a central construct used in
+templates to reference template-specific information such as the
+current URI, inheritance structures, and other things that are
+not as hard as they sound right here. Namespaces are described
+in :ref:`namespaces_toplevel`.
+
+<%inherit>
+----------
+
+Inherit allows templates to arrange themselves in **inheritance
+chains**. This is a concept familiar in many other template
+languages.
+
+.. sourcecode:: mako
+
+    <%inherit file="base.html"/>
+
+When using the %inherit tag, control is passed to the topmost
+inherited template first, which then decides how to handle
+calling areas of content from its inheriting templates. Mako
+offers a lot of flexbility in this area, including dynamic
+inheritance, content wrapping, and polymorphic method calls.
+Check it out in :ref:`inheritance_toplevel`.
+
+<%namespacename:defname>
+-------------------------
+
+As of Mako 0.2.3, any user-defined "tag" can be created against
+a namespace by using a tag with a name of the form
+``<%<namespacename>:<defname>>``. The closed and open formats of such a
+tag are equivalent to an inline expression and the ``<%call>``
+tag, respectively.
+
+.. sourcecode:: mako
+
+    <%mynamespace:somedef param="some value">
+        this is the body
+    </%mynamespace:somedef>
+
+To create custom tags which accept a body, see
+:ref:`defs_with_content`.
+
+<%call>
+-------
+
+The call tag is the "classic" form of a user-defined tag, and is
+roughly equiavlent to the ``<%namespacename:defname>`` syntax
+described above. This tag is also described in `defs_with_content`.
+
+<%doc>
+------
+
+The doc tag handles multiline comments:
+
+.. sourcecode:: mako
+
+    <%doc>
+        these are comments
+        more comments
+    </%doc>
+
+Also the ``##`` symbol as the first non-space characters on a line can be used for single line comments.
+
+<%text>
+-------
+
+This tag suspends the Mako lexer's normal parsing of Mako
+template directives, and returns its entire body contents as
+plain text. It is used pretty much to write documentation about
+Mako:
+
+.. sourcecode:: mako
+
+    <%text filter="h">
+        heres some fake mako ${syntax}
+        <%def name="x()">${x}</%def>
+    %CLOSETEXT
+
+Returning early from a template
+===============================
+
+Sometimes you want to stop processing a template or ``<%def>``
+method in the middle and just use the text you've accumulated so
+far. You can use a ````return```` statement inside a Python
+block to do that.
+
+.. sourcecode:: mako
+
+    % if not len(records):
+        No records found.
+        <% return %>
+    % endif
+
+Or perhaps:
+
+.. sourcecode:: mako
+
+    <%
+        if not len(records):
+            return
+    %>
+
diff --git a/lib3/mako-0.3.6/doc/build/templates/genindex.mako b/lib3/mako-0.3.6/doc/build/templates/genindex.mako
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/templates/genindex.mako
@@ -0,0 +1,72 @@
+<%inherit file="layout.mako"/>
+
+<%def name="show_title()">${_('Index')}</%def>
+
+   <h1 id="index">${_('Index')}</h1>
+
+   % for i, (key, dummy) in enumerate(genindexentries):
+    ${i != 0 and '| ' or ''}<a href="#${key}"><strong>${key}</strong></a>
+   % endfor
+
+   <hr />
+
+   % for i, (key, entries) in enumerate(genindexentries):
+<h2 id="${key}">${key}</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+    <%
+        breakat = genindexcounts[i] // 2
+        numcols = 1
+        numitems = 0
+    %>
+% for entryname, (links, subitems) in entries:
+
+<dt>
+    % if links:
+        <a href="${links[0]}">${entryname|h}</a>
+        % for link in links[1:]:
+            , <a href="${link}">[${i}]</a>
+        % endfor
+    % else:
+        ${entryname|h}
+    % endif
+    
+    % if subitems:
+  <dd><dl>
+    % for subentryname, subentrylinks in subitems:
+    <dt><a href="${subentrylinks[0]}">${subentryname|h}</a>
+            % for j, link in enumerate(subentrylinks[1:]):
+                <a href="${link}">[${j}]</a>
+            % endfor
+    </dt>
+    % endfor
+  </dl></dd>
+  % endif
+ <%
+    numitems = numitems + 1 + len(subitems)
+ %> 
+ % if numcols <2 and numitems > breakat:
+     <%
+        numcols = numcols + 1
+     %>
+        </dl></td><td width="33%" valign="top"><dl>
+% endif
+
+% endfor
+</dl></td></tr></table>
+% endfor
+
+<%def name="sidebarrel()">
+% if split_index:
+   <h4>${_('Index')}</h4>
+   <p>
+   % for i, (key, dummy) in enumerate(genindexentries):
+       ${i > 0 and '| ' or ''}
+       <a href="${pathto('genindex-' + key)}"><strong>${key}</strong></a>
+   % endfor
+   </p>
+
+   <p><a href="${pathto('genindex-all')}"><strong>${_('Full index on one page')}</strong></a></p>
+% endif
+   ${parent.sidebarrel()}
+</%def>
diff --git a/lib3/mako-0.3.6/doc/build/templates/layout.mako b/lib3/mako-0.3.6/doc/build/templates/layout.mako
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/templates/layout.mako
@@ -0,0 +1,130 @@
+## coding: utf-8
+<%inherit file="${context['mako_layout']}"/>
+
+<%def name="headers()">
+    <link rel="stylesheet" href="${pathto('_static/pygments.css', 1)}" type="text/css" />
+    <link rel="stylesheet" href="${pathto('_static/docs.css', 1)}" type="text/css" />
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+          URL_ROOT:    '${pathto("", 1)}',
+          VERSION:     '${release|h}',
+          COLLAPSE_MODINDEX: false,
+          FILE_SUFFIX: '${file_suffix}'
+      };
+    </script>
+    % for scriptfile in script_files + self.attr.local_script_files:
+        <script type="text/javascript" src="${pathto(scriptfile, 1)}"></script>
+    % endfor
+    <script type="text/javascript" src="${pathto('_static/init.js', 1)}"></script>
+    % if hasdoc('about'):
+        <link rel="author" title="${_('About these documents')}" href="${pathto('about')}" />
+    % endif
+    <link rel="index" title="${_('Index')}" href="${pathto('genindex')}" />
+    <link rel="search" title="${_('Search')}" href="${pathto('search')}" />
+    % if hasdoc('copyright'):
+        <link rel="copyright" title="${_('Copyright')}" href="${pathto('copyright')}" />
+    % endif
+    <link rel="top" title="${docstitle|h}" href="${pathto('index')}" />
+    % if parents:
+        <link rel="up" title="${parents[-1]['title']|util.striptags}" href="${parents[-1]['link']|h}" />
+    % endif
+    % if nexttopic:
+        <link rel="next" title="${nexttopic['title']|util.striptags}" href="${nexttopic['link']|h}" />
+    % endif
+    % if prevtopic:
+        <link rel="prev" title="${prevtopic['title']|util.striptags}" href="${prevtopic['link']|h}" />
+    % endif
+    ${self.extrahead()}
+</%def>
+<%def name="extrahead()"></%def>
+
+        <h1>${docstitle|h}</h1>
+
+        <div id="search">
+        Search:
+        <form class="search" action="${pathto('search')}" method="get">
+          <input type="text" name="q" size="18" /> <input type="submit" value="${_('Search')}" />
+          <input type="hidden" name="check_keywords" value="yes" />
+          <input type="hidden" name="area" value="default" />
+        </form>
+        </div>
+
+        <div class="versionheader">
+            Version: <span class="versionnum">${release}</span> Last Updated: ${last_updated}
+        </div>
+        <div class="clearboth"></div>
+
+        <div class="topnav">
+            <div id="pagecontrol">
+                <a href="${pathto('genindex')}">Index</a>
+            
+                % if sourcename:
+                <div class="sourcelink">(<a href="${pathto('_sources/' + sourcename, True)|h}">${_('view source')})</div>
+                % endif
+            </div>
+            
+            <div class="navbanner">
+                <a class="totoc" href="${pathto(master_doc)}">Table of Contents</a>
+                % if parents:
+                    % for parent in parents:
+                        » <a href="${parent['link']|h}" title="${parent['title']}">${parent['title']}</a>
+                    % endfor
+                % endif
+                % if current_page_name != master_doc:
+                » ${self.show_title()} 
+                % endif
+                
+                ${prevnext()}
+                <h2>
+                    ${self.show_title()} 
+                </h2>
+            </div>
+            % if display_toc and not current_page_name.startswith('index'):
+                ${toc}
+            % endif
+            <div class="clearboth"></div>
+        </div>
+        
+        <div class="document">
+            <div class="body">
+                ${next.body()}
+            </div>
+        </div>
+
+        <%def name="footer()">
+            <div class="bottomnav">
+                ${prevnext()}
+                <div class="doc_copyright">
+                % if hasdoc('copyright'):
+                    © <a href="${pathto('copyright')}">Copyright</a> ${copyright|h}.
+                % else:
+                    © Copyright ${copyright|h}.
+                % endif
+                % if show_sphinx:
+                    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> ${sphinx_version|h}.
+                % endif
+                </div>
+            </div>
+        </%def>
+        ${self.footer()}
+
+<%def name="prevnext()">
+<div class="prevnext">
+    % if prevtopic:
+        Previous:
+        <a href="${prevtopic['link']|h}" title="${_('previous chapter')}">${prevtopic['title']}</a>
+    % endif
+    % if nexttopic:
+        Next:
+        <a href="${nexttopic['link']|h}" title="${_('next chapter')}">${nexttopic['title']}</a>
+    % endif
+</div>
+</%def>
+
+<%def name="show_title()">
+% if title:
+    ${title}
+% endif
+</%def>
+
diff --git a/lib3/mako-0.3.6/doc/build/templates/page.mako b/lib3/mako-0.3.6/doc/build/templates/page.mako
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/templates/page.mako
@@ -0,0 +1,2 @@
+<%inherit file="layout.mako"/>
+${body| util.strip_toplevel_anchors}
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/doc/build/templates/search.mako b/lib3/mako-0.3.6/doc/build/templates/search.mako
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/templates/search.mako
@@ -0,0 +1,22 @@
+<%inherit file="layout.mako"/>
+
+<%!
+    local_script_files = ['_static/searchtools.js']
+%>
+<%def name="show_title()">${_('Search')}</%def>
+
+<div id="searchform">
+<h3>Enter Search Terms:</h3>
+<form class="search" action="${pathto('search')}" method="get">
+  <input type="text" name="q" size="18" /> <input type="submit" value="${_('Search')}" />
+  <input type="hidden" name="check_keywords" value="yes" />
+  <input type="hidden" name="area" value="default" />
+</form>
+</div>
+
+<div id="search-results"></div>
+
+<%def name="footer()">
+    ${parent.footer()}
+    <script type="text/javascript" src="searchindex.js"></script>
+</%def>
diff --git a/lib3/mako-0.3.6/doc/build/templates/site_base.mako b/lib3/mako-0.3.6/doc/build/templates/site_base.mako
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/templates/site_base.mako
@@ -0,0 +1,30 @@
+<%text>#coding:utf-8
+<%inherit file="/root.html"/>
+<%page cache_type="file" cached="True"/>
+<%!
+    in_docs=True
+%>
+</%text>
+
+<%doc>
+## TODO: pdf
+<div style="text-align:right">
+<b>PDF Download:</b> <a href="${pathto('sqlalchemy_' + release.replace('.', '_') + '.pdf', 1)}">download</a>
+</div>
+</%doc>
+
+${'<%text>'}
+${next.body()}
+${'</%text>'}
+
+<%text><%def name="style()"></%text>
+    ${self.headers()}
+    <%text>${parent.style()}</%text>
+    <link href="/css/site_docs.css" rel="stylesheet" type="text/css"></link>
+<%text></%def></%text>
+
+<%text><%def name="title()"></%text>${capture(self.show_title)|util.striptags} — ${docstitle|h}<%text></%def></%text>
+
+<%!
+    local_script_files = []
+%>
diff --git a/lib3/mako-0.3.6/doc/build/templates/static_base.mako b/lib3/mako-0.3.6/doc/build/templates/static_base.mako
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/templates/static_base.mako
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+        ${metatags and metatags or ''}
+        <title>${capture(self.show_title)|util.striptags} — ${docstitle|h}</title>
+        ${self.headers()}
+    </head>
+    <body>
+        ${next.body()}
+    </body>
+</html>
+
+
+<%!
+    local_script_files = []
+%>
diff --git a/lib3/mako-0.3.6/doc/build/unicode.rst b/lib3/mako-0.3.6/doc/build/unicode.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/unicode.rst
@@ -0,0 +1,337 @@
+.. _unicode_toplevel:
+
+===================
+The Unicode Chapter
+===================
+
+The Python language supports two ways of representing what we
+know as "strings", i.e. series of characters. In Python 2, the
+two types are ``string`` and ``unicode``, and in Python 3 they are
+``bytes`` and ``string``. A key aspect of the Python 2 ``string`` and
+Python 3 ``bytes`` types are that they contain no information
+regarding what **encoding** the data is stored in. For this
+reason they were commonly referred to as **byte strings** on
+Python 2, and Python 3 makes this name more explicit. The
+origins of this come from Python's background of being developed
+before the Unicode standard was even available, back when
+strings were C-style strings and were just that, a series of
+bytes. Strings that had only values below 128 just happened to
+be **ascii** strings and were printable on the console, whereas
+strings with values above 128 would produce all kinds of
+graphical characters and bells.
+
+Contrast the "bytestring" types with the "unicode/string" type.
+Objects of this type are created whenever you say something like
+``u"hello world"`` (or in Python 3, just ``"hello world"``). In this
+case, Python represents each character in the string internally
+using multiple bytes per character (something similar to
+UTF-16). Whats important is that when using the
+``unicode``/``string`` type to store strings, Python knows the
+data's encoding; its in its own internal format. Whereas when
+using the ``string``/``bytes`` type, it does not.
+
+When Python 2 attempts to treat a byte-string as a string, which
+means its attempting to compare/parse its characters, to coerce
+it into another encoding, or to decode it to a unicode object,
+it has to guess what the encoding is. In this case, it will
+pretty much always guess the encoding as ``ascii``...and if the
+bytestring contains bytes above value 128, you'll get an error.
+Python 3 eliminates much of this confusion by just raising an
+error unconditionally if a bytestring is used in a
+character-aware context.
+
+There is one operation that Python *can* do with a non-ascii
+bytestring, and its a great source of confusion: it can dump the
+bytestring straight out to a stream or a file, with nary a care
+what the encoding is. To Python, this is pretty much like
+dumping any other kind of binary data (like an image) to a
+stream somewhere. In Python 2, it is common to see programs that
+embed all kinds of international characters and encodings into
+plain byte-strings (i.e. using ``"hello world"`` style literals)
+can fly right through their run, sending reams of strings out to
+whereever they are going, and the programmer, seeing the same
+output as was expressed in the input, is now under the illusion
+that his or her program is Unicode-compliant. In fact, their
+program has no unicode awareness whatsoever, and similarly has
+no ability to interact with libraries that *are* unicode aware.
+Python 3 makes this much less likely by defaulting to unicode as
+the storage format for strings.
+
+The "pass through encoded data" scheme is what template
+languages like Cheetah and earlier versions of Myghty do by
+default. Mako as of version 0.2 also supports this mode of
+operation when using Python 2, using the "disable_unicode=True"
+flag. However, when using Mako in its default mode of
+unicode-aware, it requires explicitness when dealing with
+non-ascii encodings. Additionally, if you ever need to handle
+unicode strings and other kinds of encoding conversions more
+intelligently, the usage of raw bytestrings quickly becomes a
+nightmare, since you are sending the Python interpreter
+collections of bytes for which it can make no intelligent
+decisions with regards to encoding. In Python 3 Mako only allows
+usage of native, unicode strings.
+
+In normal Mako operation, all parsed template constructs and
+output streams are handled internally as Python ``unicode``
+objects. Its only at the point of :meth:`~.Template.render` that this unicode
+stream may be rendered into whatever the desired output encoding
+is. The implication here is that the template developer must
+ensure that the encoding of all non-ascii templates is explicit
+(still required in Python 3), that all non-ascii-encoded
+expressions are in one way or another converted to unicode (not
+much of a burden in Python 3), and that the output stream of the
+template is handled as a unicode stream being encoded to some
+encoding (still required in Python 3).
+
+Specifying the Encoding of a Template File
+===========================================
+
+This is the most basic encoding-related setting, and it is
+equivalent to Python's "magic encoding comment", as described in
+`pep-0263 <http://www.python.org/dev/peps/pep-0263/>`_. Any
+template that contains non-ascii characters requires that this
+comment be present so that Mako can decode to unicode (and also
+make usage of Python's AST parsing services). Mako's lexer will
+use this encoding in order to convert the template source into a
+``unicode`` object before continuing its parsing:
+
+.. sourcecode:: mako
+
+    ## -*- coding: utf-8 -*-
+
+    Alors vous imaginez ma surprise, au lever du jour, quand 
+    une drôle de petite voix m’a réveillé. Elle disait:
+     « S’il vous plaît… dessine-moi un mouton! »
+
+For the picky, the regular expression used is derived from that
+of the abovementioned pep:
+    
+.. sourcecode:: python
+
+    #.*coding[:=]\s*([-\w.]+).*\n
+
+The lexer will convert to unicode in all cases, so that if any
+characters exist in the template that are outside of the
+specified encoding (or the default of ``ascii``), the error will
+be immediate.
+
+As an alternative, the template encoding can be specified
+programmatically to either :class:`.Template` or :class:`.TemplateLookup` via
+the ``input_encoding`` parameter:
+
+.. sourcecode:: python
+
+    t = TemplateLookup(directories=['./'], input_encoding='utf-8')
+    
+The above will assume all located templates specify ``utf-8``
+encoding, unless the template itself contains its own magic
+encoding comment, which takes precedence.
+
+Handling Expressions
+=====================
+
+The next area that encoding comes into play is in expression
+constructs. By default, Mako's treatment of an expression like
+this:
+
+.. sourcecode:: mako
+
+    ${"hello world"}
+    
+looks something like this:
+
+.. sourcecode:: python
+
+    context.write(unicode("hello world"))
+
+In Python 3, its just:
+
+.. sourcecode:: python
+
+    context.write(str("hello world"))
+    
+That is, **the output of all expressions is run through the
+``unicode`` builtin**. This is the default setting, and can be
+modified to expect various encodings. The ``unicode`` step serves
+both the purpose of rendering non-string expressions into
+strings (such as integers or objects which contain ``__str()__``
+methods), and to ensure that the final output stream is
+constructed as a unicode object. The main implication of this is
+that **any raw bytestrings that contain an encoding other than
+ascii must first be decoded to a Python unicode object**. It
+means you can't say this in Python 2:
+
+.. sourcecode:: mako
+
+    ${"voix m’a réveillé."}  ## error in Python 2!
+
+You must instead say this:
+
+.. sourcecode:: mako
+
+    ${u"voix m’a réveillé."}  ## OK !
+
+Similarly, if you are reading data from a file that is streaming
+bytes, or returning data from some object that is returning a
+Python bytestring containing a non-ascii encoding, you have to
+explcitly decode to unicode first, such as:
+
+.. sourcecode:: mako
+
+    ${call_my_object().decode('utf-8')}
+    
+Note that filehandles acquired by ``open()`` in Python 3 default
+to returning "text", that is the decoding is done for you. See
+Python 3's documentation for the ``open()`` builtin for details on
+this.
+
+If you want a certain encoding applied to *all* expressions,
+override the ``unicode`` builtin with the ``decode`` builtin at the
+:class:`.Template` or :class:`.TemplateLookup` level:
+
+.. sourcecode:: python
+
+    t = Template(templatetext, default_filters=['decode.utf8'])
+
+Note that the built-in ``decode`` object is slower than the
+``unicode`` function, since unlike ``unicode`` its not a Python
+builtin, and it also checks the type of the incoming data to
+determine if string conversion is needed first.
+
+The ``default_filters`` argument can be used to entirely customize
+the filtering process of expressions. This argument is described
+in :ref:`filtering_default_filters`.
+ 
+Defining Output Encoding
+=========================
+
+Now that we have a template which produces a pure unicode output
+stream, all the hard work is done. We can take the output and do
+anything with it.
+
+As stated in the "Usage" chapter, both :class:`.Template` and
+:class:`.TemplateLookup` accept ``output_encoding`` and ``encoding_errors``
+parameters which can be used to encode the output in any Python
+supported codec:
+
+.. sourcecode:: python
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+    
+    mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
+    
+    mytemplate = mylookup.get_template("foo.txt")
+    print mytemplate.render()
+
+:meth:`~.Template.render` will return a ``bytes`` object in Python 3 if an output
+encoding is specified. By default it performs no encoding and
+returns a native string.
+
+:meth:`~.Template.render_unicode` will return the template output as a Python
+``unicode`` object (or ``string`` in Python 3):
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode()
+    
+The above method disgards the output encoding keyword argument;
+you can encode yourself by saying:
+
+.. sourcecode:: python
+
+    print mytemplate.render_unicode().encode('utf-8', 'replace')
+    
+Buffer Selection
+-----------------
+
+Mako does play some games with the style of buffering used
+internally, to maximize performance. Since the buffer is by far
+the most heavily used object in a render operation, its
+important!
+
+When calling :meth:`~.Template.render` on a template that does not specify any
+output encoding (i.e. its ``ascii``), Python's ``cStringIO`` module,
+which cannot handle encoding of non-ascii ``unicode`` objects
+(even though it can send raw bytestrings through), is used for
+buffering. Otherwise, a custom Mako class called
+``FastEncodingBuffer`` is used, which essentially is a super
+dumbed-down version of ``StringIO`` that gathers all strings into
+a list and uses ``u''.join(elements)`` to produce the final output
+- its markedly faster than ``StringIO``.
+
+.. _unicode_disabled:
+
+Saying to Heck with it: Disabling the usage of Unicode entirely
+================================================================
+
+Some segements of Mako's userbase choose to make no usage of
+Unicode whatsoever, and instead would prefer the "passthru"
+approach; all string expressions in their templates return
+encoded bytestrings, and they would like these strings to pass
+right through. The only advantage to this approach is that
+templates need not use ``u""`` for literal strings; there's an
+arguable speed improvement as well since raw bytestrings
+generally perform slightly faster than unicode objects in
+Python. For these users, assuming they're sticking with Python
+2, they can hit the ``disable_unicode=True`` flag as so:
+
+.. sourcecode:: python
+
+    # -*- encoding:utf-8 -*-
+    from mako.template import Template
+    
+    t = Template("drôle de petite voix m’a réveillé.", disable_unicode=True, input_encoding='utf-8')
+    print t.code
+
+The ``disable_unicode`` mode is strictly a Python 2 thing. It is
+not supported at all in Python 3.
+
+The generated module source code will contain elements like
+these:
+
+.. sourcecode:: python
+
+    # -*- encoding:utf-8 -*-
+    #  ...more generated code ...
+
+    def render_body(context,**pageargs):
+        context.caller_stack.push_frame()
+        try:
+            __M_locals = dict(pageargs=pageargs)
+            # SOURCE LINE 1
+            context.write('dr\xc3\xb4le de petite voix m\xe2\x80\x99a r\xc3\xa9veill\xc3\xa9.')
+            return ''
+        finally:
+            context.caller_stack.pop_frame()
+
+Where above that the string literal used within :meth:`.Context.write`
+is a regular bytestring.
+
+When ``disable_unicode=True`` is turned on, the ``default_filters``
+argument which normally defaults to ``["unicode"]`` now defaults
+to ``["str"]`` instead. Setting default_filters to the empty list
+``[]`` can remove the overhead of the ``str`` call. Also, in this
+mode you **cannot** safely call :meth:`~.Template.render_unicode` - you'll get
+unicode/decode errors.
+
+The ``h`` filter (html escape) uses a less performant pure Python
+escape function in non-unicode mode (note that in versions prior
+to 0.3.4, it used cgi.escape(), which has been replaced with a
+function that also escapes single quotes). This because
+MarkupSafe only supports Python unicode objects for non-ascii
+strings.
+
+**Rules for using disable_unicode=True**
+
+* don't use this mode unless you really, really want to and you
+  absolutely understand what you're doing
+* don't use this option just because you don't want to learn to
+  use Unicode properly; we aren't supporting user issues in this
+  mode of operation. We will however offer generous help for the
+  vast majority of users who stick to the Unicode program.
+* Python 3 is unicode by default, and the flag is not available
+  when running on Python 3.
+    
+
+
diff --git a/lib3/mako-0.3.6/doc/build/usage.rst b/lib3/mako-0.3.6/doc/build/usage.rst
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/doc/build/usage.rst
@@ -0,0 +1,484 @@
+.. _usage_toplevel:
+
+=====
+Usage
+=====
+
+Basic Usage
+===========
+
+This section describes the Python API for Mako templates. If you
+are using Mako within a web framework such as Pylons, the work
+of integrating Mako's API is already done for you, in which case
+you can skip to the next section, :ref:`syntax_toplevel`.
+
+The most basic way to create a template and render it is through
+the :class:`.Template` class::
+
+    from mako.template import Template
+    
+    mytemplate = Template("hello world!")
+    print mytemplate.render()
+    
+Above, the text argument to :class:`.Template` is **compiled** into a
+Python module representation. This module contains a function
+called ``render_body()``, which produces the output of the
+template. When ``mytemplate.render()`` is called, Mako sets up a
+runtime environment for the template and calls the
+``render_body()`` function, capturing the output into a buffer and
+returning its string contents.
+
+
+The code inside the ``render_body()`` function has access to a
+namespace of variables. You can specify these variables by
+sending them as additional keyword arguments to the :meth:`~.Template.render`
+method::
+
+    from mako.template import Template
+    
+    mytemplate = Template("hello, ${name}!")
+    print mytemplate.render(name="jack")
+    
+The :meth:`~.Template.render` method calls upon Mako to create a
+:class:`.Context` object, which stores all the variable names accessible
+to the template and also stores a buffer used to capture output.
+You can create this :class:`.Context` yourself and have the template
+render with it, using the :meth:`~.Template.render_context` method::
+
+    from mako.template import Template
+    from mako.runtime import Context
+    from StringIO import StringIO
+    
+    mytemplate = Template("hello, ${name}!")
+    buf = StringIO()
+    ctx = Context(buf, name="jack")
+    mytemplate.render_context(ctx)
+    print buf.getvalue()
+
+Using File-Based Templates
+===========================
+
+A :class:`.Template` can also load its template source code from a file,
+using the ``filename`` keyword argument::
+
+    from mako.template import Template
+    
+    mytemplate = Template(filename='/docs/mytmpl.txt')
+    print mytemplate.render()
+    
+For improved performance, a :class:`.Template` which is loaded from a
+file can also cache the source code to its generated module on
+the filesystem as a regular Python module file (i.e. a .py
+file). To do this, just add the ``module_directory`` argument to
+the template::
+
+    from mako.template import Template
+
+    mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules')
+    print mytemplate.render()
+
+When the above code is rendered, a file
+``/tmp/mako_modules/docs/mytmpl.txt.py`` is created containing the
+source code for the module. The next time a :class:`.Template` with the
+same arguments is created, this module file will be
+automatically re-used.
+
+.. _usage_templatelookup:
+
+Using TemplateLookup
+====================
+
+All of the examples thus far have dealt with the usage of a
+single :class:`.Template` object. If the code within those templates
+tries to locate another template resource, it will need some way
+to find them, using simple URI strings. For this need, the
+resolution of other templates from within a template is
+accomplished by the :class:`.TemplateLookup` class. This class is
+constructed given a list of directories in which to search for
+templates, as well as keyword arguments that will be passed to
+the :class:`.Template` objects it creates::
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+    
+    mylookup = TemplateLookup(directories=['/docs'])
+    mytemplate = Template("""<%include file="header.txt"/> hello world!""", lookup=mylookup)
+
+Above, we created a textual template which includes the file
+``"header.txt"``. In order for it to have somewhere to look for
+``"header.txt"``, we passed a :class:`.TemplateLookup` object to it, which
+will search in the directory ``/docs`` for the file ``"header.txt"``.
+
+Usually, an application will store most or all of its templates
+as text files on the filesystem. So far, all of our examples
+have been a little bit contrived in order to illustrate the
+basic concepts. But a real application would get most or all of
+its templates directly from the :class:`.TemplateLookup`, using the
+aptly named :meth:`~.TemplateLookup.get_template` method, which accepts the URI of the
+desired template::
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+    
+    mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules')
+    
+    def serve_template(templatename, **kwargs):
+        mytemplate = mylookup.get_template(templatename)
+        print mytemplate.render(**kwargs)
+
+In the example above, we create a :class:`.TemplateLookup` which will
+look for templates in the ``/docs`` directory, and will store
+generated module files in the ``/tmp/mako_modules`` directory. The
+lookup locates templates by appending the given URI to each of
+its search directories; so if you gave it a URI of
+``/etc/beans/info.txt``, it would search for the file
+``/docs/etc/beans/info.txt``, else raise a :class:`.TopLevelNotFound`
+exception, which is a custom Mako exception.
+
+When the lookup locates templates, it will also assign a ``uri``
+property to the :class:`.Template` which is the uri passed to the
+:meth:`~.TemplateLookup.get_template()` call. :class:`.Template` uses this uri to calculate the
+name of its module file. So in the above example, a
+``templatename`` argument of ``/etc/beans/info.txt`` will create a
+module file ``/tmp/mako_modules/etc/beans/info.txt.py``.
+
+Setting the Collection Size
+---------------------------
+
+The :class:`.TemplateLookup` also serves the important need of caching a
+fixed set of templates in memory at a given time, so that
+successive uri lookups do not result in full template
+compilations and/or module reloads on each request. By default,
+the :class:`.TemplateLookup` size is unbounded. You can specify a fixed
+size using the ``collection_size`` argument::
+
+    mylookup = TemplateLookup(directories=['/docs'], 
+                    module_directory='/tmp/mako_modules', collection_size=500)
+    
+The above lookup will continue to load templates into memory
+until it reaches a count of around 500. At that point, it will
+clean out a certain percentage of templates using a least
+recently used scheme.
+
+Setting Filesystem Checks
+--------------------------
+
+Another important flag on :class:`.TemplateLookup` is
+``filesystem_checks``. This defaults to ``True``, and says that each
+time a template is returned by the :meth:`~.TemplateLookup.get_template()` method, the
+revision time of the original template file is checked against
+the last time the template was loaded, and if the file is newer
+will reload its contents and recompile the template. On a
+production system, setting ``filesystem_checks`` to ``False`` can
+afford a small to moderate performance increase (depending on
+the type of filesystem used).
+
+.. _usage_unicode:
+
+Using Unicode and Encoding
+===========================
+
+Both :class:`.Template` and :class:`.TemplateLookup` accept ``output_encoding``
+and ``encoding_errors`` parameters which can be used to encode the
+output in any Python supported codec::
+
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+    
+    mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
+    
+    mytemplate = mylookup.get_template("foo.txt")
+    print mytemplate.render()
+
+When using Python 3, the :meth:`~.Template.render` method will return a ``bytes``
+object, **if** ``output_encoding`` is set. Otherwise it returns a
+``string``.
+
+Additionally, the :meth:`~.Template.render_unicode()` method exists which will
+return the template output as a Python ``unicode`` object, or in
+Python 3 a ``string``::
+
+    print mytemplate.render_unicode()
+    
+The above method disregards the output encoding keyword
+argument; you can encode yourself by saying::
+
+    print mytemplate.render_unicode().encode('utf-8', 'replace')
+    
+Note that Mako's ability to return data in any encoding and/or
+``unicode`` implies that the underlying output stream of the
+template is a Python unicode object. This behavior is described
+fully in :ref:`unicode_toplevel`.
+
+.. _handling_exceptions:
+
+Handling Exceptions
+====================
+
+Template exceptions can occur in two distinct places. One is
+when you **lookup, parse and compile** the template, the other
+is when you **run** the template. Within the running of a
+template, exceptions are thrown normally from whatever Python
+code originated the issue. Mako has its own set of exception
+classes which mostly apply to the lookup and lexer/compiler
+stages of template construction. Mako provides some library
+routines that can be used to help provide Mako-specific
+information about any exception's stack trace, as well as
+formatting the exception within textual or HTML format. In all
+cases, the main value of these handlers is that of converting
+Python filenames, line numbers, and code samples into Mako
+template filenames, line numbers, and code samples. All lines
+within a stack trace which correspond to a Mako template module
+will be converted to be against the originating template file.
+
+To format exception traces, the :func:`.text_error_template` and
+:func:`.html_error_template` functions are provided. They make usage of
+``sys.exc_info()`` to get at the most recently thrown exception.
+Usage of these handlers usually looks like::
+
+    from mako import exceptions
+    
+    try:
+        template = lookup.get_template(uri)
+        print template.render()
+    except:
+        print exceptions.text_error_template().render()
+    
+Or for the HTML render function::
+
+    from mako import exceptions
+
+    try:
+        template = lookup.get_template(uri)
+        print template.render()
+    except:
+        print exceptions.html_error_template().render()
+
+The :func:`.html_error_template` template accepts two options:
+specifying ``full=False`` causes only a section of an HTML
+document to be rendered. Specifying ``css=False`` will disable the
+default stylesheet from being rendered.
+
+E.g.::
+
+    print exceptions.html_error_template().render(full=False)
+
+The HTML render function is also available built-in to
+:class:`.Template` using the ``format_exceptions`` flag. In this case, any
+exceptions raised within the **render** stage of the template
+will result in the output being substituted with the output of
+:func:`.html_error_template`::
+
+    template = Template(filename="/foo/bar", format_exceptions=True)
+    print template.render()
+    
+Note that the compile stage of the above template occurs when
+you construct the :class:`.Template` itself, and no output stream is
+defined. Therefore exceptions which occur within the
+lookup/parse/compile stage will not be handled and will
+propagate normally. While the pre-render traceback usually will
+not include any Mako-specific lines anyway, it will mean that
+exceptions which occur previous to rendering and those which
+occur within rendering will be handled differently...so the
+try/except patterns described previously are probably of more
+general use.
+
+The underlying object used by the error template functions is
+the :class:`.RichTraceback` object. This object can also be used
+directly to provide custom error views. Here's an example usage
+which describes its general API::
+
+    from mako.exceptions import RichTraceback
+    
+    try:
+        template = lookup.get_template(uri)
+        print template.render()
+    except:
+        traceback = RichTraceback()
+        for (filename, lineno, function, line) in traceback.traceback:
+            print "File %s, line %s, in %s" % (filename, lineno, function)
+            print line, "\n"
+        print "%s: %s" % (str(traceback.error.__class__.__name__), traceback.error)
+        
+Common Framework Integrations
+=============================
+
+The Mako distribution includes a little bit of helper code for
+the purpose of using Mako in some popular web framework
+scenarios. This is a brief description of whats included.
+
+WSGI
+----
+
+A sample WSGI application is included in the distrubution in the
+file ``examples/wsgi/run_wsgi.py``. This runner is set up to pull
+files from a `templates` as well as an `htdocs` directory and
+includes a rudimental two-file layout. The WSGI runner acts as a
+fully functional standalone web server, using ``wsgiutils`` to run
+itself, and propagates GET and POST arguments from the request
+into the :class:`.Context`, can serve images, css files and other kinds
+of files, and also displays errors using Mako's included
+exception-handling utilities.
+
+Pygments
+---------
+
+A `Pygments <http://pygments.pocoo.org>`_-compatible syntax
+highlighting module is included under :mod:`mako.ext.pygmentplugin`.
+This module is used in the generation of Mako documentation and
+also contains various setuptools entry points under the heading
+``pygments.lexers``, including ``mako``, ``html+mako``, ``xml+mako``
+(see the ``setup.py`` file for all the entry points).
+
+Babel 
+------
+
+Mako provides support for extracting gettext messages from
+templates via a `Babel`_ extractor
+entry point under `mako.ext.babelplugin`.
+
+Gettext messages are extracted from all Python code sections,
+including those of control lines and expressions embedded
+in tags.
+
+`Translator
+comments <http://babel.edgewall.org/wiki/Documentation/messages.html#comments-tags-and-translator-comments-explanation>`_
+may also be extracted from Mako templates when a comment tag is
+specified to `Babel`_ (such as with
+the -c option).
+
+For example, a project ``"myproj"`` contains the following Mako
+template at ``myproj/myproj/templates/name.html``:
+
+.. sourcecode:: mako
+
+    <div id="name">
+      Name:
+      ## TRANSLATORS: This is a proper name. See the gettext
+      ## manual, section Names.
+      ${_('Francois Pinard')}
+    </div>
+
+To extract gettext messages from this template the project needs
+a Mako section in its `Babel Extraction Method Mapping
+file <http://babel.edgewall.org/wiki/Documentation/messages.html#extraction-method-mapping-and-configuration>`_
+(typically located at ``myproj/babel.cfg``)::
+
+    # Extraction from Python source files
+
+    [python: myproj/**.py]
+
+    # Extraction from Mako templates
+
+    [mako: myproj/templates/**.html]
+    input_encoding = utf-8
+
+The Mako extractor supports an optional ``input_encoding``
+parameter specifying the encoding of the templates (identical to
+:class:`.Template`/:class:`.TemplateLookup`'s ``input_encoding`` parameter).
+
+Invoking `Babel`_'s extractor at the
+command line in the project's root directory::
+
+    myproj$ pybabel extract -F babel.cfg -c "TRANSLATORS:" .
+
+Will output a gettext catalog to stdout including the following::
+
+    #. TRANSLATORS: This is a proper name. See the gettext
+    #. manual, section Names.
+    #: myproj/templates/name.html:5
+    msgid "Francois Pinard"
+    msgstr ""
+
+This is only a basic example:
+`Babel`_ can be invoked from setup.py
+and its command line options specified in the accompanying
+setup.cfg via `Babel Distutils/Setuptools
+Integration <http://babel.edgewall.org/wiki/Documentation/setup.html>`_.
+
+Comments must immediately precede a gettext message to be
+extracted. In the following case the TRANSLATORS: comment would
+not have been extracted:
+
+.. sourcecode:: mako
+
+    <div id="name">
+      ## TRANSLATORS: This is a proper name. See the gettext
+      ## manual, section Names.
+      Name: ${_('Francois Pinard')}
+    </div>
+
+See the `Babel User
+Guide <http://babel.edgewall.org/wiki/Documentation/index.html>`_
+for more information.
+
+.. _babel: http://babel.edgewall.org/
+
+
+API Reference
+=================
+
+.. autoclass:: mako.template.Template
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.template.DefTemplate
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.lookup.TemplateCollection
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.lookup.TemplateLookup
+    :show-inheritance:
+    :members:
+
+.. autoclass:: mako.exceptions.RichTraceback
+    :show-inheritance:
+
+    .. py:attribute:: error
+    
+       the exception instance.
+
+    .. py:attribute:: message
+    
+       the exception error message as unicode
+       
+    .. py:attribute:: source
+    
+       source code of the file where the error occured.  
+       if the error occured within a compiled template,
+       this is the template source.
+       
+    .. py:attribute:: lineno
+    
+       line number where the error occured.  if the error 
+       occured within a compiled template, the line number
+       is adjusted to that of the template source
+       
+    .. py:attribute:: records
+    
+       a list of 8-tuples containing the original 
+       python traceback elements, plus the 
+       filename, line number, source line, and full template source 
+       for the traceline mapped back to its originating source
+       template, if any for that traceline (else the fields are None).
+       
+    .. py:attribute:: reverse_records
+    
+       the list of records in reverse
+       traceback - a list of 4-tuples, in the same format as a regular 
+       python traceback, with template-corresponding 
+       traceback records replacing the originals
+       
+    .. py:attribute:: reverse_traceback
+    
+       the traceback list in reverse
+
+.. autofunction:: mako.exceptions.html_error_template
+
+.. autofunction:: mako.exceptions.text_error_template
+    
+
+
diff --git a/lib3/mako-0.3.6/examples/bench/basic.py b/lib3/mako-0.3.6/examples/bench/basic.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/basic.py
@@ -0,0 +1,161 @@
+# basic.py - basic benchmarks adapted from Genshi
+# Copyright (C) 2006 Edgewall Software
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#  3. The name of the author may not be used to endorse or promote
+#     products derived from this software without specific prior
+#     written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from cgi import escape
+import os
+from io import StringIO
+import sys
+import timeit
+
+__all__ = ['mako', 'mako_inheritance', 'cheetah', 'django', 'myghty', 'genshi', 'kid']
+
+def genshi(dirname, verbose=False):
+    from genshi.template import TemplateLoader
+    loader = TemplateLoader([dirname], auto_reload=False)
+    template = loader.load('template.html')
+    def render():
+        data = dict(title='Just a test', user='joe',
+                    items=['Number %d' % num for num in range(1, 15)])
+        return template.generate(**data).render('xhtml')
+
+    if verbose:
+        print(render())
+    return render
+
+def myghty(dirname, verbose=False):
+    from myghty import interp
+    interpreter = interp.Interpreter(component_root=dirname)
+    def render():
+        data = dict(title='Just a test', user='joe',
+                    items=['Number %d' % num for num in range(1, 15)])
+        buffer = StringIO()
+        interpreter.execute("template.myt", request_args=data, out_buffer=buffer)
+        return buffer.getvalue()
+    if verbose:
+        print(render())
+    return render
+
+def mako(dirname, verbose=False):
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+    lookup = TemplateLookup(directories=[dirname], filesystem_checks=False, disable_unicode=True)
+    template = lookup.get_template('template.html')
+    def render():
+        return template.render(title="Just a test", user="joe", list_items=['Number %d' % num for num in range(1,15)])
+    if verbose:
+        print(template.code, render())
+    return render
+mako_inheritance = mako
+
+def cheetah(dirname, verbose=False):
+    from Cheetah.Template import Template
+    filename = os.path.join(dirname, 'template.tmpl')
+    template = Template(file=filename)
+    def render():
+        template.__dict__.update({'title': 'Just a test', 'user': 'joe',
+                                  'list_items': ['Number %d' % num for num in range(1, 15)]})
+        return template.respond()
+
+    if verbose:
+        print(dir(template))
+        print(template.generatedModuleCode())
+        print(render())
+    return render
+
+def django(dirname, verbose=False):
+    from django.conf import settings
+    settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')])
+    from django import template, templatetags
+    from django.template import loader
+    templatetags.__path__.append(os.path.join(dirname, 'templatetags'))
+    tmpl = loader.get_template('template.html')
+
+    def render():
+        data = {'title': 'Just a test', 'user': 'joe',
+                'items': ['Number %d' % num for num in range(1, 15)]}
+        return tmpl.render(template.Context(data))
+
+    if verbose:
+        print(render())
+    return render
+
+def kid(dirname, verbose=False):
+    import kid
+    kid.path = kid.TemplatePath([dirname])
+    template = kid.Template(file='template.kid')
+    def render():
+        template = kid.Template(file='template.kid',
+                                title='Just a test', user='joe',
+                                items=['Number %d' % num for num in range(1, 15)])
+        return template.serialize(output='xhtml')
+
+    if verbose:
+        print(render())
+    return render
+
+
+def run(engines, number=2000, verbose=False):
+    basepath = os.path.abspath(os.path.dirname(__file__))
+    for engine in engines:
+        dirname = os.path.join(basepath, engine)
+        if verbose:
+            print('%s:' % engine.capitalize())
+            print('--------------------------------------------------------')
+        else:
+            print('%s:' % engine.capitalize(), end=' ')
+        t = timeit.Timer(setup='from __main__ import %s; render = %s(r"%s", %s)'
+                                       % (engine, engine, dirname, verbose),
+                                 stmt='render()')
+            
+        time = t.timeit(number=number) / number
+        if verbose:
+            print('--------------------------------------------------------')
+        print('%.2f ms' % (1000 * time))
+        if verbose:
+            print('--------------------------------------------------------')
+
+
+if __name__ == '__main__':
+    engines = [arg for arg in sys.argv[1:] if arg[0] != '-']
+    if not engines:
+        engines = __all__
+
+    verbose = '-v' in sys.argv
+
+    if '-p' in sys.argv:
+        import hotshot, hotshot.stats
+        prof = hotshot.Profile("template.prof")
+        benchtime = prof.runcall(run, engines, number=100, verbose=verbose)
+        stats = hotshot.stats.load("template.prof")
+        stats.strip_dirs()
+        stats.sort_stats('time', 'calls')
+        stats.print_stats()
+    else:
+        run(engines, verbose=verbose)
diff --git a/lib3/mako-0.3.6/examples/bench/basic.py.orig b/lib3/mako-0.3.6/examples/bench/basic.py.orig
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/basic.py.orig
@@ -0,0 +1,161 @@
+# basic.py - basic benchmarks adapted from Genshi
+# Copyright (C) 2006 Edgewall Software
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 
+#  1. Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#  2. Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#  3. The name of the author may not be used to endorse or promote
+#     products derived from this software without specific prior
+#     written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from cgi import escape
+import os
+from StringIO import StringIO
+import sys
+import timeit
+
+__all__ = ['mako', 'mako_inheritance', 'cheetah', 'django', 'myghty', 'genshi', 'kid']
+
+def genshi(dirname, verbose=False):
+    from genshi.template import TemplateLoader
+    loader = TemplateLoader([dirname], auto_reload=False)
+    template = loader.load('template.html')
+    def render():
+        data = dict(title='Just a test', user='joe',
+                    items=['Number %d' % num for num in range(1, 15)])
+        return template.generate(**data).render('xhtml')
+
+    if verbose:
+        print render()
+    return render
+
+def myghty(dirname, verbose=False):
+    from myghty import interp
+    interpreter = interp.Interpreter(component_root=dirname)
+    def render():
+        data = dict(title='Just a test', user='joe',
+                    items=['Number %d' % num for num in range(1, 15)])
+        buffer = StringIO()
+        interpreter.execute("template.myt", request_args=data, out_buffer=buffer)
+        return buffer.getvalue()
+    if verbose:
+        print render()
+    return render
+
+def mako(dirname, verbose=False):
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+    lookup = TemplateLookup(directories=[dirname], filesystem_checks=False, disable_unicode=True)
+    template = lookup.get_template('template.html')
+    def render():
+        return template.render(title="Just a test", user="joe", list_items=[u'Number %d' % num for num in range(1,15)])
+    if verbose:
+        print template.code, render()
+    return render
+mako_inheritance = mako
+
+def cheetah(dirname, verbose=False):
+    from Cheetah.Template import Template
+    filename = os.path.join(dirname, 'template.tmpl')
+    template = Template(file=filename)
+    def render():
+        template.__dict__.update({'title': 'Just a test', 'user': 'joe',
+                                  'list_items': [u'Number %d' % num for num in range(1, 15)]})
+        return template.respond()
+
+    if verbose:
+        print dir(template)
+        print template.generatedModuleCode()
+        print render()
+    return render
+
+def django(dirname, verbose=False):
+    from django.conf import settings
+    settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')])
+    from django import template, templatetags
+    from django.template import loader
+    templatetags.__path__.append(os.path.join(dirname, 'templatetags'))
+    tmpl = loader.get_template('template.html')
+
+    def render():
+        data = {'title': 'Just a test', 'user': 'joe',
+                'items': ['Number %d' % num for num in range(1, 15)]}
+        return tmpl.render(template.Context(data))
+
+    if verbose:
+        print render()
+    return render
+
+def kid(dirname, verbose=False):
+    import kid
+    kid.path = kid.TemplatePath([dirname])
+    template = kid.Template(file='template.kid')
+    def render():
+        template = kid.Template(file='template.kid',
+                                title='Just a test', user='joe',
+                                items=['Number %d' % num for num in range(1, 15)])
+        return template.serialize(output='xhtml')
+
+    if verbose:
+        print render()
+    return render
+
+
+def run(engines, number=2000, verbose=False):
+    basepath = os.path.abspath(os.path.dirname(__file__))
+    for engine in engines:
+        dirname = os.path.join(basepath, engine)
+        if verbose:
+            print '%s:' % engine.capitalize()
+            print '--------------------------------------------------------'
+        else:
+            print '%s:' % engine.capitalize(),
+        t = timeit.Timer(setup='from __main__ import %s; render = %s(r"%s", %s)'
+                                       % (engine, engine, dirname, verbose),
+                                 stmt='render()')
+            
+        time = t.timeit(number=number) / number
+        if verbose:
+            print '--------------------------------------------------------'
+        print '%.2f ms' % (1000 * time)
+        if verbose:
+            print '--------------------------------------------------------'
+
+
+if __name__ == '__main__':
+    engines = [arg for arg in sys.argv[1:] if arg[0] != '-']
+    if not engines:
+        engines = __all__
+
+    verbose = '-v' in sys.argv
+
+    if '-p' in sys.argv:
+        import hotshot, hotshot.stats
+        prof = hotshot.Profile("template.prof")
+        benchtime = prof.runcall(run, engines, number=100, verbose=verbose)
+        stats = hotshot.stats.load("template.prof")
+        stats.strip_dirs()
+        stats.sort_stats('time', 'calls')
+        stats.print_stats()
+    else:
+        run(engines, verbose=verbose)
diff --git a/lib3/mako-0.3.6/examples/bench/cheetah/footer.tmpl b/lib3/mako-0.3.6/examples/bench/cheetah/footer.tmpl
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/cheetah/footer.tmpl
@@ -0,0 +1,2 @@
+<div id="footer">
+</div>
diff --git a/lib3/mako-0.3.6/examples/bench/cheetah/header.tmpl b/lib3/mako-0.3.6/examples/bench/cheetah/header.tmpl
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/cheetah/header.tmpl
@@ -0,0 +1,5 @@
+<div id="header">
+  <h1>$title</h1>
+</div>
+
+
diff --git a/lib3/mako-0.3.6/examples/bench/cheetah/template.tmpl b/lib3/mako-0.3.6/examples/bench/cheetah/template.tmpl
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/cheetah/template.tmpl
@@ -0,0 +1,31 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+  <head>
+    <title>${title}</title>
+  </head>
+  <body>
+
+      #def greeting(name)
+      <p>hello ${name}!</p>
+      #end def
+      
+    #include "cheetah/header.tmpl"
+
+    $greeting($user)
+    $greeting('me')
+    $greeting('world')
+    
+    <h2>Loop</h2>
+    #if $list_items
+      <ul>
+        #for $list_item in $list_items
+          <li #if $list_item is $list_items[-1] then "class='last'" else ""#>$list_item</li>
+        #end for
+      </ul>
+    #end if
+
+    #include "cheetah/footer.tmpl"
+  </body>
+</html>
diff --git a/lib3/mako-0.3.6/examples/bench/django/templates/base.html b/lib3/mako-0.3.6/examples/bench/django/templates/base.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/django/templates/base.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+
+  {% block body %}
+    <div id="header">
+      <h1>{{ title|escape }}</h1>
+    </div>
+    {{ block.super }}
+    <div id="footer"></div>
+  {% endblock %}
+
+</html>
diff --git a/lib3/mako-0.3.6/examples/bench/django/templates/template.html b/lib3/mako-0.3.6/examples/bench/django/templates/template.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/django/templates/template.html
@@ -0,0 +1,22 @@
+{% extends "base.html" %}
+{% load bench %}
+
+<head>
+  <title>${title|escape}</title>
+</head>
+
+{% block body %}
+  <div>{% greeting user %}</div>
+  <div>{% greeting "me" %}</div>
+  <div>{% greeting "world" %}</div>
+
+  <h2>Loop</h2>
+  {% if items %}
+    <ul>
+      {% for item in items %}
+	<li{% if forloop.last %} class="last"{% endif %}>{{ item }}</li>
+      {% endfor %}
+    </ul>
+  {% endif %}
+
+{% endblock %}
diff --git a/lib3/mako-0.3.6/examples/bench/django/templatetags/bench.py b/lib3/mako-0.3.6/examples/bench/django/templatetags/bench.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/django/templatetags/bench.py
@@ -0,0 +1,8 @@
+from django.template import Library, Node, resolve_variable
+from django.utils.html import escape
+
+register = Library()
+
+def greeting(name):
+    return 'Hello, %s!' % escape(name)
+greeting = register.simple_tag(greeting)
diff --git a/lib3/mako-0.3.6/examples/bench/genshi/base.html b/lib3/mako-0.3.6/examples/bench/genshi/base.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/genshi/base.html
@@ -0,0 +1,17 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://genshi.edgewall.org/"
+      py:strip="">
+
+  <p py:def="greeting(name)">
+    Hello, ${name}!
+  </p>
+
+  <body py:match="body">
+    <div id="header">
+      <h1>${title}</h1>
+    </div>
+    ${select('*')}
+    <div id="footer" />
+  </body>
+
+</html>
diff --git a/lib3/mako-0.3.6/examples/bench/genshi/template.html b/lib3/mako-0.3.6/examples/bench/genshi/template.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/genshi/template.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://genshi.edgewall.org/"
+      xmlns:xi="http://www.w3.org/2001/XInclude"
+      lang="en">
+  <xi:include href="base.html" />
+  <head>
+    <title>${title}</title>
+  </head>
+  <body>
+    <div>${greeting(user)}</div>
+    <div>${greeting('me')}</div>
+    <div>${greeting('world')}</div>
+
+    <h2>Loop</h2>
+    <ul py:if="items">
+      <li py:for="idx, item in enumerate(items)" py:content="item"
+          class="${idx + 1 == len(items) and 'last' or None}" />
+    </ul>
+
+  </body>
+</html>
diff --git a/lib3/mako-0.3.6/examples/bench/kid/base.kid b/lib3/mako-0.3.6/examples/bench/kid/base.kid
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/kid/base.kid
@@ -0,0 +1,15 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://purl.org/kid/ns#">
+
+  <p py:def="greeting(name)">
+    Hello, ${name}!
+  </p>
+
+  <body py:match="item.tag == '{http://www.w3.org/1999/xhtml}body'" py:strip="">
+    <div id="header">
+      <h1>${title}</h1>
+    </div>
+    ${item}
+    <div id="footer" />
+  </body>
+</html>
diff --git a/lib3/mako-0.3.6/examples/bench/kid/template.kid b/lib3/mako-0.3.6/examples/bench/kid/template.kid
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/kid/template.kid
@@ -0,0 +1,22 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:py="http://purl.org/kid/ns#"
+      py:extends="'base.kid'"
+      lang="en">
+  <head>
+    <title>${title}</title>
+  </head>
+  <body>
+    <div>${greeting(user)}</div>
+    <div>${greeting('me')}</div>
+    <div>${greeting('world')}</div>
+    
+    <h2>Loop</h2>
+    <ul py:if="items">
+      <li py:for="idx, item in enumerate(items)" py:content="item"
+          class="${idx + 1 == len(items) and 'last' or None}" />
+    </ul>
+  </body>
+</html>
diff --git a/lib3/mako-0.3.6/examples/bench/mako/footer.html b/lib3/mako-0.3.6/examples/bench/mako/footer.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/mako/footer.html
@@ -0,0 +1,2 @@
+<div id="footer">
+</div>
diff --git a/lib3/mako-0.3.6/examples/bench/mako/header.html b/lib3/mako-0.3.6/examples/bench/mako/header.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/mako/header.html
@@ -0,0 +1,5 @@
+<div id="header">
+  <h1>${title}</h1>
+</div>
+
+
diff --git a/lib3/mako-0.3.6/examples/bench/mako/template.html b/lib3/mako-0.3.6/examples/bench/mako/template.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/mako/template.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+  <head>
+    <title>${title}</title>
+  </head>
+  <body>
+
+<%def name="greeting(name)">
+      <p>hello ${name}!</p>
+</%def>
+      
+ <%include file="header.html"/>
+
+    ${greeting(user)}
+    ${greeting('me')}
+    ${greeting('world')}
+    
+    <h2>Loop</h2>
+    % if list_items:
+      <ul>
+        % for i, list_item in enumerate(list_items):
+	<li ${i+1==len(list_items) and "class='last'" or ""}>${list_item}</li>
+        % endfor
+      </ul>
+    % endif
+
+    <%include file="footer.html"/>
+  </body>
+</html>
diff --git a/lib3/mako-0.3.6/examples/bench/mako_inheritance/base.html b/lib3/mako-0.3.6/examples/bench/mako_inheritance/base.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/mako_inheritance/base.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+  <head>
+    <title>${title}</title>
+  </head>
+  <body>
+
+<%def name="greeting(name)">
+      <p>hello ${name}!</p>
+</%def>
+      
+<div id="header">
+  <h1>${title}</h1>
+</div>
+
+ ${self.body()}
+
+ <div id="footer">
+ </div>
+
+  </body>
+</html>
diff --git a/lib3/mako-0.3.6/examples/bench/mako_inheritance/template.html b/lib3/mako-0.3.6/examples/bench/mako_inheritance/template.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/mako_inheritance/template.html
@@ -0,0 +1,15 @@
+<%inherit file="base.html"/>
+
+    ${parent.greeting(user)}
+    ${parent.greeting('me')}
+    ${parent.greeting('world')}
+    
+    <h2>Loop</h2>
+    % if list_items:
+      <ul>
+        % for list_item in list_items:
+          <li>${list_item}</li>
+        % endfor
+      </ul>
+    % endif
+
diff --git a/lib3/mako-0.3.6/examples/bench/myghty/base.myt b/lib3/mako-0.3.6/examples/bench/myghty/base.myt
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/myghty/base.myt
@@ -0,0 +1,29 @@
+<!DOCTYPE html
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+<%args scope="request">
+    title
+</%args>
+
+<& REQUEST:header &>
+
+<body>
+<div id="header">
+  <h1><% title %></h1>
+</div>
+
+% m.call_next()
+
+<div id="footer"></div>
+
+</body>
+</html>
+
+
+<%method greeting>
+<%args>
+   name
+</%args>
+Hello, <% name | h %>
+</%method>
diff --git a/lib3/mako-0.3.6/examples/bench/myghty/template.myt b/lib3/mako-0.3.6/examples/bench/myghty/template.myt
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/bench/myghty/template.myt
@@ -0,0 +1,30 @@
+<%flags>inherit="base.myt"</%flags>
+<%args>
+	title
+	items
+	user
+</%args>
+
+<%method header>
+    <%args scope="request">
+    title
+    </%args>
+<head>
+  <title><% title %></title>
+</head>
+</%method>
+
+  <div><& base.myt:greeting, name=user &></div>
+  <div><& base.myt:greeting, name="me"&></div>
+  <div><& base.myt:greeting, name="world" &></div>
+
+  <h2>Loop</h2>
+%if items:
+      <ul>
+%	for i, item in enumerate(items):
+  <li <% i+1==len(items) and "class='last'" or ""%>><% item %></li>
+%
+      </ul>
+%
+
+ 
diff --git a/lib3/mako-0.3.6/examples/wsgi/htdocs/index.html b/lib3/mako-0.3.6/examples/wsgi/htdocs/index.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/wsgi/htdocs/index.html
@@ -0,0 +1,8 @@
+<%
+%>
+
+<%inherit file="root.html"/>
+
+This is index.html
+    
+c is ${c is not UNDEFINED and c or "undefined"}
diff --git a/lib3/mako-0.3.6/examples/wsgi/run_wsgi.py b/lib3/mako-0.3.6/examples/wsgi/run_wsgi.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/wsgi/run_wsgi.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+import cgi, re, os, posixpath, mimetypes
+from mako.lookup import TemplateLookup
+from mako import exceptions
+
+root = './'
+port = 8000
+error_style = 'html' # select 'text' for plaintext error reporting
+
+lookup = TemplateLookup(directories=[root + 'templates', root + 'htdocs'], filesystem_checks=True, module_directory='./modules')
+
+def serve(environ, start_response):
+    """serves requests using the WSGI callable interface."""
+    fieldstorage = cgi.FieldStorage(
+            fp = environ['wsgi.input'],
+            environ = environ,
+            keep_blank_values = True
+    )
+    d = dict([(k, getfield(fieldstorage[k])) for k in fieldstorage])
+
+    uri = environ.get('PATH_INFO', '/')
+    if not uri:
+        uri = '/index.html'
+    else:
+        uri = re.sub(r'^/$', '/index.html', uri)
+
+    if re.match(r'.*\.html$', uri):
+        try:
+            template = lookup.get_template(uri)
+            start_response("200 OK", [('Content-type','text/html')])
+            return [template.render(**d)]
+        except exceptions.TopLevelLookupException:
+            start_response("404 Not Found", [])
+            return ["Cant find template '%s'" % uri]
+        except:
+            if error_style == 'text':
+                start_response("200 OK", [('Content-type','text/plain')])
+                return [exceptions.text_error_template().render()]
+            else:
+                start_response("200 OK", [('Content-type','text/html')])
+                return [exceptions.html_error_template().render()]
+    else:
+        u = re.sub(r'^\/+', '', uri)
+        filename = os.path.join(root, u)
+        start_response("200 OK", [('Content-type',guess_type(uri))])
+        return [file(filename).read()]
+        
+def getfield(f):
+    """convert values from cgi.Field objects to plain values."""
+    if isinstance(f, list):
+        return [getfield(x) for x in f]
+    else:
+        return f.value
+
+extensions_map = mimetypes.types_map.copy()
+extensions_map.update({
+'': 'text/html', # Default
+})
+
+def guess_type(path):
+    """return a mimetype for the given path based on file extension."""
+    base, ext = posixpath.splitext(path)
+    if ext in extensions_map:
+        return extensions_map[ext]
+    ext = ext.lower()
+    if ext in extensions_map:
+        return extensions_map[ext]
+    else:
+        return extensions_map['']
+        
+if __name__ == '__main__':
+    import wsgiref.simple_server
+    server = wsgiref.simple_server.make_server('', port, serve)
+    print("Server listening on port %d" % port)
+    server.serve_forever()
+
+
diff --git a/lib3/mako-0.3.6/examples/wsgi/templates/root.html b/lib3/mako-0.3.6/examples/wsgi/templates/root.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/examples/wsgi/templates/root.html
@@ -0,0 +1,7 @@
+<html>
+
+<head><title>hi</title></head>
+<body>
+    ${next.body()}
+</body>
+</html>
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/mako/__init__.py b/lib3/mako-0.3.6/mako/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/__init__.py
@@ -0,0 +1,9 @@
+# __init__.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+
+__version__ = '0.3.6'
+
diff --git a/lib3/mako-0.3.6/mako/_ast_util.py b/lib3/mako-0.3.6/mako/_ast_util.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/_ast_util.py
@@ -0,0 +1,834 @@
+# -*- coding: utf-8 -*-
+"""
+    ast
+    ~~~
+
+    The `ast` module helps Python applications to process trees of the Python
+    abstract syntax grammar.  The abstract syntax itself might change with
+    each Python release; this module helps to find out programmatically what
+    the current grammar looks like and allows modifications of it.
+
+    An abstract syntax tree can be generated by passing `ast.PyCF_ONLY_AST` as
+    a flag to the `compile()` builtin function or by using the `parse()`
+    function from this module.  The result will be a tree of objects whose
+    classes all inherit from `ast.AST`.
+
+    A modified abstract syntax tree can be compiled into a Python code object
+    using the built-in `compile()` function.
+
+    Additionally various helper functions are provided that make working with
+    the trees simpler.  The main intention of the helper functions and this
+    module in general is to provide an easy to use interface for libraries
+    that work tightly with the python syntax (template engines for example).
+
+
+    :copyright: Copyright 2008 by Armin Ronacher.
+    :license: Python License.
+"""
+from _ast import *
+
+
+BOOLOP_SYMBOLS = {
+    And:        'and',
+    Or:         'or'
+}
+
+BINOP_SYMBOLS = {
+    Add:        '+',
+    Sub:        '-',
+    Mult:       '*',
+    Div:        '/',
+    FloorDiv:   '//',
+    Mod:        '%',
+    LShift:     '<<',
+    RShift:     '>>',
+    BitOr:      '|',
+    BitAnd:     '&',
+    BitXor:     '^'
+}
+
+CMPOP_SYMBOLS = {
+    Eq:         '==',
+    Gt:         '>',
+    GtE:        '>=',
+    In:         'in',
+    Is:         'is',
+    IsNot:      'is not',
+    Lt:         '<',
+    LtE:        '<=',
+    NotEq:      '!=',
+    NotIn:      'not in'
+}
+
+UNARYOP_SYMBOLS = {
+    Invert:     '~',
+    Not:        'not',
+    UAdd:       '+',
+    USub:       '-'
+}
+
+ALL_SYMBOLS = {}
+ALL_SYMBOLS.update(BOOLOP_SYMBOLS)
+ALL_SYMBOLS.update(BINOP_SYMBOLS)
+ALL_SYMBOLS.update(CMPOP_SYMBOLS)
+ALL_SYMBOLS.update(UNARYOP_SYMBOLS)
+
+
+def parse(expr, filename='<unknown>', mode='exec'):
+    """Parse an expression into an AST node."""
+    return compile(expr, filename, mode, PyCF_ONLY_AST)
+
+
+def to_source(node, indent_with=' ' * 4):
+    """
+    This function can convert a node tree back into python sourcecode.  This
+    is useful for debugging purposes, especially if you're dealing with custom
+    asts not generated by python itself.
+
+    It could be that the sourcecode is evaluable when the AST itself is not
+    compilable / evaluable.  The reason for this is that the AST contains some
+    more data than regular sourcecode does, which is dropped during
+    conversion.
+
+    Each level of indentation is replaced with `indent_with`.  Per default this
+    parameter is equal to four spaces as suggested by PEP 8, but it might be
+    adjusted to match the application's styleguide.
+    """
+    generator = SourceGenerator(indent_with)
+    generator.visit(node)
+    return ''.join(generator.result)
+
+
+def dump(node):
+    """
+    A very verbose representation of the node passed.  This is useful for
+    debugging purposes.
+    """
+    def _format(node):
+        if isinstance(node, AST):
+            return '%s(%s)' % (node.__class__.__name__,
+                               ', '.join('%s=%s' % (a, _format(b))
+                                         for a, b in iter_fields(node)))
+        elif isinstance(node, list):
+            return '[%s]' % ', '.join(_format(x) for x in node)
+        return repr(node)
+    if not isinstance(node, AST):
+        raise TypeError('expected AST, got %r' % node.__class__.__name__)
+    return _format(node)
+
+
+def copy_location(new_node, old_node):
+    """
+    Copy the source location hint (`lineno` and `col_offset`) from the
+    old to the new node if possible and return the new one.
+    """
+    for attr in 'lineno', 'col_offset':
+        if attr in old_node._attributes and attr in new_node._attributes \
+           and hasattr(old_node, attr):
+            setattr(new_node, attr, getattr(old_node, attr))
+    return new_node
+
+
+def fix_missing_locations(node):
+    """
+    Some nodes require a line number and the column offset.  Without that
+    information the compiler will abort the compilation.  Because it can be
+    a dull task to add appropriate line numbers and column offsets when
+    adding new nodes this function can help.  It copies the line number and
+    column offset of the parent node to the child nodes without this
+    information.
+
+    Unlike `copy_location` this works recursive and won't touch nodes that
+    already have a location information.
+    """
+    def _fix(node, lineno, col_offset):
+        if 'lineno' in node._attributes:
+            if not hasattr(node, 'lineno'):
+                node.lineno = lineno
+            else:
+                lineno = node.lineno
+        if 'col_offset' in node._attributes:
+            if not hasattr(node, 'col_offset'):
+                node.col_offset = col_offset
+            else:
+                col_offset = node.col_offset
+        for child in iter_child_nodes(node):
+            _fix(child, lineno, col_offset)
+    _fix(node, 1, 0)
+    return node
+
+
+def increment_lineno(node, n=1):
+    """
+    Increment the line numbers of all nodes by `n` if they have line number
+    attributes.  This is useful to "move code" to a different location in a
+    file.
+    """
+    for node in zip((node,), walk(node)):
+        if 'lineno' in node._attributes:
+            node.lineno = getattr(node, 'lineno', 0) + n
+
+
+def iter_fields(node):
+    """Iterate over all fields of a node, only yielding existing fields."""
+    # CPython 2.5 compat
+    if not hasattr(node, '_fields') or not node._fields:
+        return
+    for field in node._fields:
+        try:
+            yield field, getattr(node, field)
+        except AttributeError:
+            pass
+
+
+def get_fields(node):
+    """Like `iter_fiels` but returns a dict."""
+    return dict(iter_fields(node))
+
+
+def iter_child_nodes(node):
+    """Iterate over all child nodes or a node."""
+    for name, field in iter_fields(node):
+        if isinstance(field, AST):
+            yield field
+        elif isinstance(field, list):
+            for item in field:
+                if isinstance(item, AST):
+                    yield item
+
+
+def get_child_nodes(node):
+    """Like `iter_child_nodes` but returns a list."""
+    return list(iter_child_nodes(node))
+
+
+def get_compile_mode(node):
+    """
+    Get the mode for `compile` of a given node.  If the node is not a `mod`
+    node (`Expression`, `Module` etc.) a `TypeError` is thrown.
+    """
+    if not isinstance(node, mod):
+        raise TypeError('expected mod node, got %r' % node.__class__.__name__)
+    return {
+        Expression:     'eval',
+        Interactive:    'single'
+    }.get(node.__class__, 'expr')
+
+
+def get_docstring(node):
+    """
+    Return the docstring for the given node or `None` if no docstring can be
+    found.  If the node provided does not accept docstrings a `TypeError`
+    will be raised.
+    """
+    if not isinstance(node, (FunctionDef, ClassDef, Module)):
+        raise TypeError("%r can't have docstrings" % node.__class__.__name__)
+    if node.body and isinstance(node.body[0], Str):
+        return node.body[0].s
+
+
+def walk(node):
+    """
+    Iterate over all nodes.  This is useful if you only want to modify nodes in
+    place and don't care about the context or the order the nodes are returned.
+    """
+    from collections import deque
+    todo = deque([node])
+    while todo:
+        node = todo.popleft()
+        todo.extend(iter_child_nodes(node))
+        yield node
+
+
+class NodeVisitor(object):
+    """
+    Walks the abstract syntax tree and call visitor functions for every node
+    found.  The visitor functions may return values which will be forwarded
+    by the `visit` method.
+
+    Per default the visitor functions for the nodes are ``'visit_'`` +
+    class name of the node.  So a `TryFinally` node visit function would
+    be `visit_TryFinally`.  This behavior can be changed by overriding
+    the `get_visitor` function.  If no visitor function exists for a node
+    (return value `None`) the `generic_visit` visitor is used instead.
+
+    Don't use the `NodeVisitor` if you want to apply changes to nodes during
+    traversing.  For this a special visitor exists (`NodeTransformer`) that
+    allows modifications.
+    """
+
+    def get_visitor(self, node):
+        """
+        Return the visitor function for this node or `None` if no visitor
+        exists for this node.  In that case the generic visit function is
+        used instead.
+        """
+        method = 'visit_' + node.__class__.__name__
+        return getattr(self, method, None)
+
+    def visit(self, node):
+        """Visit a node."""
+        f = self.get_visitor(node)
+        if f is not None:
+            return f(node)
+        return self.generic_visit(node)
+
+    def generic_visit(self, node):
+        """Called if no explicit visitor function exists for a node."""
+        for field, value in iter_fields(node):
+            if isinstance(value, list):
+                for item in value:
+                    if isinstance(item, AST):
+                        self.visit(item)
+            elif isinstance(value, AST):
+                self.visit(value)
+
+
+class NodeTransformer(NodeVisitor):
+    """
+    Walks the abstract syntax tree and allows modifications of nodes.
+
+    The `NodeTransformer` will walk the AST and use the return value of the
+    visitor functions to replace or remove the old node.  If the return
+    value of the visitor function is `None` the node will be removed
+    from the previous location otherwise it's replaced with the return
+    value.  The return value may be the original node in which case no
+    replacement takes place.
+
+    Here an example transformer that rewrites all `foo` to `data['foo']`::
+
+        class RewriteName(NodeTransformer):
+
+            def visit_Name(self, node):
+                return copy_location(Subscript(
+                    value=Name(id='data', ctx=Load()),
+                    slice=Index(value=Str(s=node.id)),
+                    ctx=node.ctx
+                ), node)
+
+    Keep in mind that if the node you're operating on has child nodes
+    you must either transform the child nodes yourself or call the generic
+    visit function for the node first.
+
+    Nodes that were part of a collection of statements (that applies to
+    all statement nodes) may also return a list of nodes rather than just
+    a single node.
+
+    Usually you use the transformer like this::
+
+        node = YourTransformer().visit(node)
+    """
+
+    def generic_visit(self, node):
+        for field, old_value in iter_fields(node):
+            old_value = getattr(node, field, None)
+            if isinstance(old_value, list):
+                new_values = []
+                for value in old_value:
+                    if isinstance(value, AST):
+                        value = self.visit(value)
+                        if value is None:
+                            continue
+                        elif not isinstance(value, AST):
+                            new_values.extend(value)
+                            continue
+                    new_values.append(value)
+                old_value[:] = new_values
+            elif isinstance(old_value, AST):
+                new_node = self.visit(old_value)
+                if new_node is None:
+                    delattr(node, field)
+                else:
+                    setattr(node, field, new_node)
+        return node
+
+
+class SourceGenerator(NodeVisitor):
+    """
+    This visitor is able to transform a well formed syntax tree into python
+    sourcecode.  For more details have a look at the docstring of the
+    `node_to_source` function.
+    """
+
+    def __init__(self, indent_with):
+        self.result = []
+        self.indent_with = indent_with
+        self.indentation = 0
+        self.new_lines = 0
+
+    def write(self, x):
+        if self.new_lines:
+            if self.result:
+                self.result.append('\n' * self.new_lines)
+            self.result.append(self.indent_with * self.indentation)
+            self.new_lines = 0
+        self.result.append(x)
+
+    def newline(self, n=1):
+        self.new_lines = max(self.new_lines, n)
+
+    def body(self, statements):
+        self.new_line = True
+        self.indentation += 1
+        for stmt in statements:
+            self.visit(stmt)
+        self.indentation -= 1
+
+    def body_or_else(self, node):
+        self.body(node.body)
+        if node.orelse:
+            self.newline()
+            self.write('else:')
+            self.body(node.orelse)
+
+    def signature(self, node):
+        want_comma = []
+        def write_comma():
+            if want_comma:
+                self.write(', ')
+            else:
+                want_comma.append(True)
+
+        padding = [None] * (len(node.args) - len(node.defaults))
+        for arg, default in zip(node.args, padding + node.defaults):
+            write_comma()
+            self.visit(arg)
+            if default is not None:
+                self.write('=')
+                self.visit(default)
+        if node.vararg is not None:
+            write_comma()
+            self.write('*' + node.vararg)
+        if node.kwarg is not None:
+            write_comma()
+            self.write('**' + node.kwarg)
+
+    def decorators(self, node):
+        for decorator in node.decorator_list:
+            self.newline()
+            self.write('@')
+            self.visit(decorator)
+
+    # Statements
+
+    def visit_Assign(self, node):
+        self.newline()
+        for idx, target in enumerate(node.targets):
+            if idx:
+                self.write(', ')
+            self.visit(target)
+        self.write(' = ')
+        self.visit(node.value)
+
+    def visit_AugAssign(self, node):
+        self.newline()
+        self.visit(node.target)
+        self.write(BINOP_SYMBOLS[type(node.op)] + '=')
+        self.visit(node.value)
+
+    def visit_ImportFrom(self, node):
+        self.newline()
+        self.write('from %s%s import ' % ('.' * node.level, node.module))
+        for idx, item in enumerate(node.names):
+            if idx:
+                self.write(', ')
+            self.write(item)
+
+    def visit_Import(self, node):
+        self.newline()
+        for item in node.names:
+            self.write('import ')
+            self.visit(item)
+
+    def visit_Expr(self, node):
+        self.newline()
+        self.generic_visit(node)
+
+    def visit_FunctionDef(self, node):
+        self.newline(n=2)
+        self.decorators(node)
+        self.newline()
+        self.write('def %s(' % node.name)
+        self.signature(node.args)
+        self.write('):')
+        self.body(node.body)
+
+    def visit_ClassDef(self, node):
+        have_args = []
+        def paren_or_comma():
+            if have_args:
+                self.write(', ')
+            else:
+                have_args.append(True)
+                self.write('(')
+
+        self.newline(n=3)
+        self.decorators(node)
+        self.newline()
+        self.write('class %s' % node.name)
+        for base in node.bases:
+            paren_or_comma()
+            self.visit(base)
+        # XXX: the if here is used to keep this module compatible
+        #      with python 2.6.
+        if hasattr(node, 'keywords'):
+            for keyword in node.keywords:
+                paren_or_comma()
+                self.write(keyword.arg + '=')
+                self.visit(keyword.value)
+            if node.starargs is not None:
+                paren_or_comma()
+                self.write('*')
+                self.visit(node.starargs)
+            if node.kwargs is not None:
+                paren_or_comma()
+                self.write('**')
+                self.visit(node.kwargs)
+        self.write(have_args and '):' or ':')
+        self.body(node.body)
+
+    def visit_If(self, node):
+        self.newline()
+        self.write('if ')
+        self.visit(node.test)
+        self.write(':')
+        self.body(node.body)
+        while True:
+            else_ = node.orelse
+            if len(else_) == 1 and isinstance(else_[0], If):
+                node = else_[0]
+                self.newline()
+                self.write('elif ')
+                self.visit(node.test)
+                self.write(':')
+                self.body(node.body)
+            else:
+                self.newline()
+                self.write('else:')
+                self.body(else_)
+                break
+
+    def visit_For(self, node):
+        self.newline()
+        self.write('for ')
+        self.visit(node.target)
+        self.write(' in ')
+        self.visit(node.iter)
+        self.write(':')
+        self.body_or_else(node)
+
+    def visit_While(self, node):
+        self.newline()
+        self.write('while ')
+        self.visit(node.test)
+        self.write(':')
+        self.body_or_else(node)
+
+    def visit_With(self, node):
+        self.newline()
+        self.write('with ')
+        self.visit(node.context_expr)
+        if node.optional_vars is not None:
+            self.write(' as ')
+            self.visit(node.optional_vars)
+        self.write(':')
+        self.body(node.body)
+
+    def visit_Pass(self, node):
+        self.newline()
+        self.write('pass')
+
+    def visit_Print(self, node):
+        # XXX: python 2.6 only
+        self.newline()
+        self.write('print ')
+        want_comma = False
+        if node.dest is not None:
+            self.write(' >> ')
+            self.visit(node.dest)
+            want_comma = True
+        for value in node.values:
+            if want_comma:
+                self.write(', ')
+            self.visit(value)
+            want_comma = True
+        if not node.nl:
+            self.write(',')
+
+    def visit_Delete(self, node):
+        self.newline()
+        self.write('del ')
+        for idx, target in enumerate(node):
+            if idx:
+                self.write(', ')
+            self.visit(target)
+
+    def visit_TryExcept(self, node):
+        self.newline()
+        self.write('try:')
+        self.body(node.body)
+        for handler in node.handlers:
+            self.visit(handler)
+
+    def visit_TryFinally(self, node):
+        self.newline()
+        self.write('try:')
+        self.body(node.body)
+        self.newline()
+        self.write('finally:')
+        self.body(node.finalbody)
+
+    def visit_Global(self, node):
+        self.newline()
+        self.write('global ' + ', '.join(node.names))
+
+    def visit_Nonlocal(self, node):
+        self.newline()
+        self.write('nonlocal ' + ', '.join(node.names))
+
+    def visit_Return(self, node):
+        self.newline()
+        self.write('return ')
+        self.visit(node.value)
+
+    def visit_Break(self, node):
+        self.newline()
+        self.write('break')
+
+    def visit_Continue(self, node):
+        self.newline()
+        self.write('continue')
+
+    def visit_Raise(self, node):
+        # XXX: Python 2.6 / 3.0 compatibility
+        self.newline()
+        self.write('raise')
+        if hasattr(node, 'exc') and node.exc is not None:
+            self.write(' ')
+            self.visit(node.exc)
+            if node.cause is not None:
+                self.write(' from ')
+                self.visit(node.cause)
+        elif hasattr(node, 'type') and node.type is not None:
+            self.visit(node.type)
+            if node.inst is not None:
+                self.write(', ')
+                self.visit(node.inst)
+            if node.tback is not None:
+                self.write(', ')
+                self.visit(node.tback)
+
+    # Expressions
+
+    def visit_Attribute(self, node):
+        self.visit(node.value)
+        self.write('.' + node.attr)
+
+    def visit_Call(self, node):
+        want_comma = []
+        def write_comma():
+            if want_comma:
+                self.write(', ')
+            else:
+                want_comma.append(True)
+
+        self.visit(node.func)
+        self.write('(')
+        for arg in node.args:
+            write_comma()
+            self.visit(arg)
+        for keyword in node.keywords:
+            write_comma()
+            self.write(keyword.arg + '=')
+            self.visit(keyword.value)
+        if node.starargs is not None:
+            write_comma()
+            self.write('*')
+            self.visit(node.starargs)
+        if node.kwargs is not None:
+            write_comma()
+            self.write('**')
+            self.visit(node.kwargs)
+        self.write(')')
+
+    def visit_Name(self, node):
+        self.write(node.id)
+
+    def visit_Str(self, node):
+        self.write(repr(node.s))
+
+    def visit_Bytes(self, node):
+        self.write(repr(node.s))
+
+    def visit_Num(self, node):
+        self.write(repr(node.n))
+
+    def visit_Tuple(self, node):
+        self.write('(')
+        idx = -1
+        for idx, item in enumerate(node.elts):
+            if idx:
+                self.write(', ')
+            self.visit(item)
+        self.write(idx and ')' or ',)')
+
+    def sequence_visit(left, right):
+        def visit(self, node):
+            self.write(left)
+            for idx, item in enumerate(node.elts):
+                if idx:
+                    self.write(', ')
+                self.visit(item)
+            self.write(right)
+        return visit
+
+    visit_List = sequence_visit('[', ']')
+    visit_Set = sequence_visit('{', '}')
+    del sequence_visit
+
+    def visit_Dict(self, node):
+        self.write('{')
+        for idx, (key, value) in enumerate(zip(node.keys, node.values)):
+            if idx:
+                self.write(', ')
+            self.visit(key)
+            self.write(': ')
+            self.visit(value)
+        self.write('}')
+
+    def visit_BinOp(self, node):
+        self.write('(')
+        self.visit(node.left)
+        self.write(' %s ' % BINOP_SYMBOLS[type(node.op)])
+        self.visit(node.right)
+        self.write(')')
+
+    def visit_BoolOp(self, node):
+        self.write('(')
+        for idx, value in enumerate(node.values):
+            if idx:
+                self.write(' %s ' % BOOLOP_SYMBOLS[type(node.op)])
+            self.visit(value)
+        self.write(')')
+
+    def visit_Compare(self, node):
+        self.write('(')
+        self.visit(node.left)
+        for op, right in zip(node.ops, node.comparators):
+            self.write(' %s ' % CMPOP_SYMBOLS[type(op)])
+            self.visit(right)
+        self.write(')')
+
+    def visit_UnaryOp(self, node):
+        self.write('(')
+        op = UNARYOP_SYMBOLS[type(node.op)]
+        self.write(op)
+        if op == 'not':
+            self.write(' ')
+        self.visit(node.operand)
+        self.write(')')
+
+    def visit_Subscript(self, node):
+        self.visit(node.value)
+        self.write('[')
+        self.visit(node.slice)
+        self.write(']')
+
+    def visit_Slice(self, node):
+        if node.lower is not None:
+            self.visit(node.lower)
+        self.write(':')
+        if node.upper is not None:
+            self.visit(node.upper)
+        if node.step is not None:
+            self.write(':')
+            if not (isinstance(node.step, Name) and node.step.id == 'None'):
+                self.visit(node.step)
+
+    def visit_ExtSlice(self, node):
+        for idx, item in node.dims:
+            if idx:
+                self.write(', ')
+            self.visit(item)
+
+    def visit_Yield(self, node):
+        self.write('yield ')
+        self.visit(node.value)
+
+    def visit_Lambda(self, node):
+        self.write('lambda ')
+        self.signature(node.args)
+        self.write(': ')
+        self.visit(node.body)
+
+    def visit_Ellipsis(self, node):
+        self.write('Ellipsis')
+
+    def generator_visit(left, right):
+        def visit(self, node):
+            self.write(left)
+            self.visit(node.elt)
+            for comprehension in node.generators:
+                self.visit(comprehension)
+            self.write(right)
+        return visit
+
+    visit_ListComp = generator_visit('[', ']')
+    visit_GeneratorExp = generator_visit('(', ')')
+    visit_SetComp = generator_visit('{', '}')
+    del generator_visit
+
+    def visit_DictComp(self, node):
+        self.write('{')
+        self.visit(node.key)
+        self.write(': ')
+        self.visit(node.value)
+        for comprehension in node.generators:
+            self.visit(comprehension)
+        self.write('}')
+
+    def visit_IfExp(self, node):
+        self.visit(node.body)
+        self.write(' if ')
+        self.visit(node.test)
+        self.write(' else ')
+        self.visit(node.orelse)
+
+    def visit_Starred(self, node):
+        self.write('*')
+        self.visit(node.value)
+
+    def visit_Repr(self, node):
+        # XXX: python 2.6 only
+        self.write('`')
+        self.visit(node.value)
+        self.write('`')
+
+    # Helper Nodes
+
+    def visit_alias(self, node):
+        self.write(node.name)
+        if node.asname is not None:
+            self.write(' as ' + node.asname)
+
+    def visit_comprehension(self, node):
+        self.write(' for ')
+        self.visit(node.target)
+        self.write(' in ')
+        self.visit(node.iter)
+        if node.ifs:
+            for if_ in node.ifs:
+                self.write(' if ')
+                self.visit(if_)
+
+    def visit_excepthandler(self, node):
+        self.newline()
+        self.write('except')
+        if node.type is not None:
+            self.write(' ')
+            self.visit(node.type)
+            if node.name is not None:
+                self.write(' as ')
+                self.visit(node.name)
+        self.write(':')
+        self.body(node.body)
diff --git a/lib3/mako-0.3.6/mako/ast.py b/lib3/mako-0.3.6/mako/ast.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/ast.py
@@ -0,0 +1,143 @@
+# ast.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""utilities for analyzing expressions and blocks of Python 
+code, as well as generating Python from AST nodes"""
+
+from mako import exceptions, pyparser, util
+import re
+
+class PythonCode(object):
+    """represents information about a string containing Python code"""
+    def __init__(self, code, **exception_kwargs):
+        self.code = code
+        
+        # represents all identifiers which are assigned to at some point in the code
+        self.declared_identifiers = set()
+        
+        # represents all identifiers which are referenced before their assignment, if any
+        self.undeclared_identifiers = set()
+        
+        # note that an identifier can be in both the undeclared and declared lists.
+
+        # using AST to parse instead of using code.co_varnames, 
+        # code.co_names has several advantages:
+        # - we can locate an identifier as "undeclared" even if 
+        # its declared later in the same block of code
+        # - AST is less likely to break with version changes 
+        # (for example, the behavior of co_names changed a little bit
+        # in python version 2.5)
+        if isinstance(code, str):
+            expr = pyparser.parse(code.lstrip(), "exec", **exception_kwargs)
+        else:
+            expr = code
+
+        f = pyparser.FindIdentifiers(self, **exception_kwargs)
+        f.visit(expr)
+
+class ArgumentList(object):
+    """parses a fragment of code as a comma-separated list of expressions"""
+    def __init__(self, code, **exception_kwargs):
+        self.codeargs = []
+        self.args = []
+        self.declared_identifiers = set()
+        self.undeclared_identifiers = set()
+        if isinstance(code, str):
+            if re.match(r"\S", code) and not re.match(r",\s*$", code):
+                # if theres text and no trailing comma, insure its parsed
+                # as a tuple by adding a trailing comma
+                code  += ","
+            expr = pyparser.parse(code, "exec", **exception_kwargs)
+        else:
+            expr = code
+
+        f = pyparser.FindTuple(self, PythonCode, **exception_kwargs)
+        f.visit(expr)
+        
+class PythonFragment(PythonCode):
+    """extends PythonCode to provide identifier lookups in partial control statements
+    
+    e.g. 
+        for x in 5:
+        elif y==9:
+        except (MyException, e):
+    etc.
+    """
+    def __init__(self, code, **exception_kwargs):
+        m = re.match(r'^(\w+)(?:\s+(.*?))?:\s*(#|$)', code.strip(), re.S)
+        if not m:
+            raise exceptions.CompileException(
+                            "Fragment '%s' is not a partial control statement" % 
+                            code, **exception_kwargs)
+        if m.group(3):
+            code = code[:m.start(3)]
+        (keyword, expr) = m.group(1,2)
+        if keyword in ['for','if', 'while']:
+            code = code + "pass"
+        elif keyword == 'try':
+            code = code + "pass\nexcept:pass"
+        elif keyword == 'elif' or keyword == 'else':
+            code = "if False:pass\n" + code + "pass"
+        elif keyword == 'except':
+            code = "try:pass\n" + code + "pass"
+        else:
+            raise exceptions.CompileException(
+                                "Unsupported control keyword: '%s'" % 
+                                keyword, **exception_kwargs)
+        super(PythonFragment, self).__init__(code, **exception_kwargs)
+        
+        
+class FunctionDecl(object):
+    """function declaration"""
+    def __init__(self, code, allow_kwargs=True, **exception_kwargs):
+        self.code = code
+        expr = pyparser.parse(code, "exec", **exception_kwargs)
+                
+        f = pyparser.ParseFunc(self, **exception_kwargs)
+        f.visit(expr)
+        if not hasattr(self, 'funcname'):
+            raise exceptions.CompileException(
+                                "Code '%s' is not a function declaration" % code,
+                                **exception_kwargs)
+        if not allow_kwargs and self.kwargs:
+            raise exceptions.CompileException(
+                                "'**%s' keyword argument not allowed here" % 
+                                self.argnames[-1], **exception_kwargs)
+            
+    def get_argument_expressions(self, include_defaults=True):
+        """return the argument declarations of this FunctionDecl as a printable list."""
+        
+        namedecls = []
+        defaults = [d for d in self.defaults]
+        kwargs = self.kwargs
+        varargs = self.varargs
+        argnames = [f for f in self.argnames]
+        argnames.reverse()
+        for arg in argnames:
+            default = None
+            if kwargs:
+                arg = "**" + arg
+                kwargs = False
+            elif varargs:
+                arg = "*" + arg
+                varargs = False
+            else:
+                default = len(defaults) and defaults.pop() or None
+            if include_defaults and default:
+                namedecls.insert(0, "%s=%s" % 
+                            (arg, 
+                            pyparser.ExpressionGenerator(default).value()
+                            )
+                        )
+            else:
+                namedecls.insert(0, arg)
+        return namedecls
+
+class FunctionArgs(FunctionDecl):
+    """the argument portion of a function declaration"""
+    
+    def __init__(self, code, **kwargs):
+        super(FunctionArgs, self).__init__("def ANON(%s):pass" % code, **kwargs)
diff --git a/lib3/mako-0.3.6/mako/cache.py b/lib3/mako-0.3.6/mako/cache.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/cache.py
@@ -0,0 +1,118 @@
+from mako import exceptions
+
+cache = None
+
+class BeakerMissing(object):
+    def get_cache(self, name, **kwargs):
+        raise exceptions.RuntimeException("the Beaker package is required to use cache functionality.")
+
+class Cache(object):
+    """Represents a data content cache made available to the module
+    space of a :class:`.Template` object.
+    
+    :class:`.Cache` is a wrapper on top of a Beaker CacheManager object.
+    This object in turn references any number of "containers", each of
+    which defines its own backend (i.e. file, memory, memcached, etc.) 
+    independently of the rest.
+    
+    """
+    
+    def __init__(self, id, starttime):
+        self.id = id
+        self.starttime = starttime
+        self.def_regions = {}
+        
+    def put(self, key, value, **kwargs):
+        """Place a value in the cache.
+        
+        :param key: the value's key.
+        :param value: the value
+        :param \**kwargs: cache configuration arguments.  The 
+         backend is configured using these arguments upon first request.
+         Subsequent requests that use the same series of configuration
+         values will use that same backend.
+        
+        """
+        
+        defname = kwargs.pop('defname', None)
+        expiretime = kwargs.pop('expiretime', None)
+        createfunc = kwargs.pop('createfunc', None)
+        
+        self._get_cache(defname, **kwargs).put_value(key, starttime=self.starttime, expiretime=expiretime)
+        
+    def get(self, key, **kwargs):
+        """Retrieve a value from the cache.
+        
+        :param key: the value's key.
+        :param \**kwargs: cache configuration arguments.  The 
+         backend is configured using these arguments upon first request.
+         Subsequent requests that use the same series of configuration
+         values will use that same backend.
+        
+        """
+        
+        defname = kwargs.pop('defname', None)
+        expiretime = kwargs.pop('expiretime', None)
+        createfunc = kwargs.pop('createfunc', None)
+        
+        return self._get_cache(defname, **kwargs).get_value(key, starttime=self.starttime, expiretime=expiretime, createfunc=createfunc)
+        
+    def invalidate(self, key, **kwargs):
+        """Invalidate a value in the cache.
+        
+        :param key: the value's key.
+        :param \**kwargs: cache configuration arguments.  The 
+         backend is configured using these arguments upon first request.
+         Subsequent requests that use the same series of configuration
+         values will use that same backend.
+        
+        """
+        defname = kwargs.pop('defname', None)
+        expiretime = kwargs.pop('expiretime', None)
+        createfunc = kwargs.pop('createfunc', None)
+        
+        self._get_cache(defname, **kwargs).remove_value(key, starttime=self.starttime, expiretime=expiretime)
+    
+    def invalidate_body(self):
+        """Invalidate the cached content of the "body" method for this template.
+        
+        """
+        self.invalidate('render_body', defname='render_body')
+    
+    def invalidate_def(self, name):
+        """Invalidate the cached content of a particular <%def> within this template."""
+        
+        self.invalidate('render_%s' % name, defname='render_%s' % name)
+        
+    def invalidate_closure(self, name):
+        """Invalidate a nested <%def> within this template.
+        
+        Caching of nested defs is a blunt tool as there is no
+        management of scope - nested defs that use cache tags
+        need to have names unique of all other nested defs in the 
+        template, else their content will be overwritten by 
+        each other.
+        
+        """
+        
+        self.invalidate(name, defname=name)
+    
+    def _get_cache(self, defname, type=None, **kw):
+        global cache
+        if not cache:
+            try:
+                from beaker import cache as beaker_cache
+                cache = beaker_cache.CacheManager()
+            except ImportError:
+                # keep a fake cache around so subsequent 
+                # calls don't attempt to re-import
+                cache = BeakerMissing()
+
+        if type == 'memcached':
+            type = 'ext:memcached'
+        if not type:
+            (type, kw) = self.def_regions.get(defname, ('memory', {}))
+        else:
+            self.def_regions[defname] = (type, kw)
+        return cache.get_cache(self.id, type=type, **kw)
+        
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/mako/codegen.py b/lib3/mako-0.3.6/mako/codegen.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/codegen.py
@@ -0,0 +1,958 @@
+# codegen.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""provides functionality for rendering a parsetree constructing into module source code."""
+
+import time
+import re
+from mako.pygen import PythonPrinter
+from mako import util, ast, parsetree, filters
+
+MAGIC_NUMBER = 5
+
+def compile(node, 
+                uri, 
+                filename=None, 
+                default_filters=None, 
+                buffer_filters=None, 
+                imports=None, 
+                source_encoding=None, 
+                generate_magic_comment=True,
+                disable_unicode=False,
+                strict_undefined=False):
+                
+    """Generate module source code given a parsetree node, 
+      uri, and optional source filename"""
+
+    # if on Py2K, push the "source_encoding" string to be
+    # a bytestring itself, as we will be embedding it into 
+    # the generated source and we don't want to coerce the 
+    # result into a unicode object, in "disable_unicode" mode
+    if not util.py3k and isinstance(source_encoding, str):
+        source_encoding = source_encoding.encode(source_encoding)
+        
+        
+    buf = util.FastEncodingBuffer()
+
+    printer = PythonPrinter(buf)
+    _GenerateRenderMethod(printer, 
+                            _CompileContext(uri, 
+                                            filename, 
+                                            default_filters, 
+                                            buffer_filters,
+                                            imports, 
+                                            source_encoding,
+                                            generate_magic_comment,
+                                            disable_unicode,
+                                            strict_undefined), 
+                                node)
+    return buf.getvalue()
+
+class _CompileContext(object):
+    def __init__(self, 
+                    uri, 
+                    filename, 
+                    default_filters, 
+                    buffer_filters, 
+                    imports, 
+                    source_encoding, 
+                    generate_magic_comment,
+                    disable_unicode,
+                    strict_undefined):
+        self.uri = uri
+        self.filename = filename
+        self.default_filters = default_filters
+        self.buffer_filters = buffer_filters
+        self.imports = imports
+        self.source_encoding = source_encoding
+        self.generate_magic_comment = generate_magic_comment
+        self.disable_unicode = disable_unicode
+        self.strict_undefined = strict_undefined
+        
+class _GenerateRenderMethod(object):
+    """A template visitor object which generates the 
+       full module source for a template.
+       
+    """
+    def __init__(self, printer, compiler, node):
+        self.printer = printer
+        self.last_source_line = -1
+        self.compiler = compiler
+        self.node = node
+        self.identifier_stack = [None]
+        
+        self.in_def = isinstance(node, parsetree.DefTag)
+
+        if self.in_def:
+            name = "render_" + node.name
+            args = node.function_decl.get_argument_expressions()
+            filtered = len(node.filter_args.args) > 0 
+            buffered = eval(node.attributes.get('buffered', 'False'))
+            cached = eval(node.attributes.get('cached', 'False'))
+            defs = None
+            pagetag = None
+        else:
+            defs = self.write_toplevel()
+            pagetag = self.compiler.pagetag
+            name = "render_body"
+            if pagetag is not None:
+                args = pagetag.body_decl.get_argument_expressions()
+                if not pagetag.body_decl.kwargs:
+                    args += ['**pageargs']
+                cached = eval(pagetag.attributes.get('cached', 'False'))
+            else:
+                args = ['**pageargs']
+                cached = False
+            buffered = filtered = False
+        if args is None:
+            args = ['context']
+        else:
+            args = [a for a in ['context'] + args]
+            
+        self.write_render_callable(
+                            pagetag or node, 
+                            name, args, 
+                            buffered, filtered, cached)
+        
+        if defs is not None:
+            for node in defs:
+                _GenerateRenderMethod(printer, compiler, node)
+    
+    @property
+    def identifiers(self):
+        return self.identifier_stack[-1]
+    
+    def write_toplevel(self):
+        """Traverse a template structure for module-level directives and
+        generate the start of module-level code.
+        
+        """
+        inherit = []
+        namespaces = {}
+        module_code = []
+        encoding =[None]
+
+        self.compiler.pagetag = None
+        
+        class FindTopLevel(object):
+            def visitInheritTag(s, node):
+                inherit.append(node)
+            def visitNamespaceTag(s, node):
+                namespaces[node.name] = node
+            def visitPageTag(s, node):
+                self.compiler.pagetag = node
+            def visitCode(s, node):
+                if node.ismodule:
+                    module_code.append(node)
+            
+        f = FindTopLevel()
+        for n in self.node.nodes:
+            n.accept_visitor(f)
+
+        self.compiler.namespaces = namespaces
+
+        module_ident = set()
+        for n in module_code:
+            module_ident = module_ident.union(n.declared_identifiers())
+
+        module_identifiers = _Identifiers()
+        module_identifiers.declared = module_ident
+        
+        # module-level names, python code
+        if self.compiler.generate_magic_comment and \
+            self.compiler.source_encoding:
+            self.printer.writeline("# -*- encoding:%s -*-" %
+                                    self.compiler.source_encoding)
+            
+        self.printer.writeline("from mako import runtime, filters, cache")
+        self.printer.writeline("UNDEFINED = runtime.UNDEFINED")
+        self.printer.writeline("__M_dict_builtin = dict")
+        self.printer.writeline("__M_locals_builtin = locals")
+        self.printer.writeline("_magic_number = %r" % MAGIC_NUMBER)
+        self.printer.writeline("_modified_time = %r" % time.time())
+        self.printer.writeline(
+                            "_template_filename=%r" % self.compiler.filename)
+        self.printer.writeline("_template_uri=%r" % self.compiler.uri)
+        self.printer.writeline(
+                    "_template_cache=cache.Cache(__name__, _modified_time)")
+        self.printer.writeline(
+                    "_source_encoding=%r" % self.compiler.source_encoding)
+        if self.compiler.imports:
+            buf = ''
+            for imp in self.compiler.imports:
+                buf += imp + "\n"
+                self.printer.writeline(imp)
+            impcode = ast.PythonCode(
+                            buf, 
+                            source='', lineno=0, 
+                            pos=0, 
+                            filename='template defined imports')
+        else:
+            impcode = None
+        
+        main_identifiers = module_identifiers.branch(self.node)
+        module_identifiers.topleveldefs = \
+            module_identifiers.topleveldefs.\
+                union(main_identifiers.topleveldefs)
+        module_identifiers.declared.add("UNDEFINED")
+        if impcode:
+            module_identifiers.declared.update(impcode.declared_identifiers)
+            
+        self.compiler.identifiers = module_identifiers
+        self.printer.writeline("_exports = %r" % 
+                            [n.name for n in
+                            list(main_identifiers.topleveldefs.values())]
+                        )
+        self.printer.write("\n\n")
+
+        if len(module_code):
+            self.write_module_code(module_code)
+
+        if len(inherit):
+            self.write_namespaces(namespaces)
+            self.write_inherit(inherit[-1])
+        elif len(namespaces):
+            self.write_namespaces(namespaces)
+
+        return list(main_identifiers.topleveldefs.values())
+
+    def write_render_callable(self, node, name, args, buffered, filtered, cached):
+        """write a top-level render callable.
+        
+        this could be the main render() method or that of a top-level def."""
+        
+        if self.in_def:
+            decorator = node.decorator
+            if decorator:
+                self.printer.writeline("@runtime._decorate_toplevel(%s)" % decorator)
+        
+        self.printer.writelines(
+            "def %s(%s):" % (name, ','.join(args)),
+                "context.caller_stack._push_frame()",
+                "try:"
+        )
+        if buffered or filtered or cached:
+            self.printer.writeline("context._push_buffer()")
+        
+        self.identifier_stack.append(self.compiler.identifiers.branch(self.node))
+        if not self.in_def and '**pageargs' in args:
+            self.identifier_stack[-1].argument_declared.add('pageargs')
+
+        if not self.in_def and (
+                                len(self.identifiers.locally_assigned) > 0 or
+                                len(self.identifiers.argument_declared) > 0
+                                ):
+            self.printer.writeline("__M_locals = __M_dict_builtin(%s)" % 
+                                    ','.join([
+                                            "%s=%s" % (x, x) for x in
+                                            self.identifiers.argument_declared
+                                            ]))
+
+        self.write_variable_declares(self.identifiers, toplevel=True)
+
+        for n in self.node.nodes:
+            n.accept_visitor(self)
+
+        self.write_def_finish(self.node, buffered, filtered, cached)
+        self.printer.writeline(None)
+        self.printer.write("\n\n")
+        if cached:
+            self.write_cache_decorator(
+                                node, name, 
+                                args, buffered, 
+                                self.identifiers, toplevel=True)
+            
+    def write_module_code(self, module_code):
+        """write module-level template code, i.e. that which 
+        is enclosed in <%! %> tags in the template."""
+        for n in module_code:
+            self.write_source_comment(n)
+            self.printer.write_indented_block(n.text)
+
+    def write_inherit(self, node):
+        """write the module-level inheritance-determination callable."""
+        
+        self.printer.writelines(
+            "def _mako_inherit(template, context):",
+                "_mako_generate_namespaces(context)",
+                "return runtime._inherit_from(context, %s, _template_uri)" %
+                 (node.parsed_attributes['file']),
+                None
+            )
+
+    def write_namespaces(self, namespaces):
+        """write the module-level namespace-generating callable."""
+        self.printer.writelines(
+            "def _mako_get_namespace(context, name):",
+                "try:",
+                    "return context.namespaces[(__name__, name)]",
+                "except KeyError:",
+                    "_mako_generate_namespaces(context)",
+                "return context.namespaces[(__name__, name)]",
+            None,None
+            )
+        self.printer.writeline("def _mako_generate_namespaces(context):")
+
+        
+        for node in list(namespaces.values()):
+            if 'import' in node.attributes:
+                self.compiler.has_ns_imports = True
+            self.write_source_comment(node)
+            if len(node.nodes):
+                self.printer.writeline("def make_namespace():")
+                export = []
+                identifiers = self.compiler.identifiers.branch(node)
+                self.in_def = True
+                class NSDefVisitor(object):
+                    def visitDefTag(s, node):
+                        self.write_inline_def(node, identifiers, nested=False)
+                        export.append(node.name)
+                vis = NSDefVisitor()
+                for n in node.nodes:
+                    n.accept_visitor(vis)
+                self.printer.writeline("return [%s]" % (','.join(export)))
+                self.printer.writeline(None)
+                self.in_def = False
+                callable_name = "make_namespace()"
+            else:
+                callable_name = "None"
+            self.printer.writeline(
+                            "ns = runtime.Namespace(%r, context._clean_inheritance_tokens(),"
+                            " templateuri=%s, callables=%s, calling_uri=_template_uri, module=%s)" %
+                            (
+                                node.name,
+                                node.parsed_attributes.get('file', 'None'), 
+                                callable_name, 
+                                node.parsed_attributes.get('module', 'None'))
+                            )
+            if eval(node.attributes.get('inheritable', "False")):
+                self.printer.writeline("context['self'].%s = ns" % (node.name))
+                
+            self.printer.writeline("context.namespaces[(__name__, %s)] = ns" % repr(node.name))
+            self.printer.write("\n")
+        if not len(namespaces):
+            self.printer.writeline("pass")
+        self.printer.writeline(None)
+            
+    def write_variable_declares(self, identifiers, toplevel=False, limit=None):
+        """write variable declarations at the top of a function.
+        
+        the variable declarations are in the form of callable
+        definitions for defs and/or name lookup within the
+        function's context argument. the names declared are based
+        on the names that are referenced in the function body,
+        which don't otherwise have any explicit assignment
+        operation. names that are assigned within the body are
+        assumed to be locally-scoped variables and are not
+        separately declared.
+        
+        for def callable definitions, if the def is a top-level
+        callable then a 'stub' callable is generated which wraps
+        the current Context into a closure. if the def is not
+        top-level, it is fully rendered as a local closure.
+        
+        """
+        
+        # collection of all defs available to us in this scope
+        comp_idents = dict([(c.name, c) for c in identifiers.defs])
+        to_write = set()
+        
+        # write "context.get()" for all variables we are going to 
+        # need that arent in the namespace yet
+        to_write = to_write.union(identifiers.undeclared)
+        
+        # write closure functions for closures that we define 
+        # right here
+        to_write = to_write.union([c.name for c in list(identifiers.closuredefs.values())])
+
+        # remove identifiers that are declared in the argument 
+        # signature of the callable
+        to_write = to_write.difference(identifiers.argument_declared)
+
+        # remove identifiers that we are going to assign to.  
+        # in this way we mimic Python's behavior,
+        # i.e. assignment to a variable within a block 
+        # means that variable is now a "locally declared" var,
+        # which cannot be referenced beforehand.  
+        to_write = to_write.difference(identifiers.locally_declared)
+        
+        # if a limiting set was sent, constraint to those items in that list
+        # (this is used for the caching decorator)
+        if limit is not None:
+            to_write = to_write.intersection(limit)
+        
+        if toplevel and getattr(self.compiler, 'has_ns_imports', False):
+            self.printer.writeline("_import_ns = {}")
+            self.compiler.has_imports = True
+            for ident, ns in self.compiler.namespaces.items():
+                if 'import' in ns.attributes:
+                    self.printer.writeline(
+                            "_mako_get_namespace(context, %r)._populate(_import_ns, %r)" %
+                            (
+                                ident,
+                                re.split(r'\s*,\s*', ns.attributes['import'])
+                            ))
+                        
+        for ident in to_write:
+            if ident in comp_idents:
+                comp = comp_idents[ident]
+                if comp.is_root():
+                    self.write_def_decl(comp, identifiers)
+                else:
+                    self.write_inline_def(comp, identifiers, nested=True)
+            elif ident in self.compiler.namespaces:
+                self.printer.writeline(
+                            "%s = _mako_get_namespace(context, %r)" % 
+                                (ident, ident)
+                            )
+            else:
+                if getattr(self.compiler, 'has_ns_imports', False):
+                    if self.compiler.strict_undefined:
+                        self.printer.writelines(
+                        "%s = _import_ns.get(%r, UNDEFINED)" % 
+                        (ident, ident),
+                        "if %s is UNDEFINED:" % ident,
+                            "try:",
+                                "%s = context[%r]" % (ident, ident),
+                            "except KeyError:",
+                                "raise NameError(\"'%s' is not defined\")" % 
+                                    ident,
+                            None, None
+                        )
+                    else:
+                        self.printer.writeline(
+                        "%s = _import_ns.get(%r, context.get(%r, UNDEFINED))" % 
+                        (ident, ident, ident))
+                else:
+                    if self.compiler.strict_undefined:
+                        self.printer.writelines(
+                            "try:",
+                                "%s = context[%r]" % (ident, ident),
+                            "except KeyError:",
+                                "raise NameError(\"'%s' is not defined\")" % 
+                                    ident,
+                            None
+                        )
+                    else:
+                        self.printer.writeline(
+                            "%s = context.get(%r, UNDEFINED)" % (ident, ident)
+                        )
+        
+        self.printer.writeline("__M_writer = context.writer()")
+        
+    def write_source_comment(self, node):
+        """write a source comment containing the line number of the corresponding template line."""
+        if self.last_source_line != node.lineno:
+            self.printer.writeline("# SOURCE LINE %d" % node.lineno)
+            self.last_source_line = node.lineno
+
+    def write_def_decl(self, node, identifiers):
+        """write a locally-available callable referencing a top-level def"""
+        funcname = node.function_decl.funcname
+        namedecls = node.function_decl.get_argument_expressions()
+        nameargs = node.function_decl.get_argument_expressions(include_defaults=False)
+        
+        if not self.in_def and (
+                                len(self.identifiers.locally_assigned) > 0 or
+                                len(self.identifiers.argument_declared) > 0):
+            nameargs.insert(0, 'context.locals_(__M_locals)')
+        else:
+            nameargs.insert(0, 'context')
+        self.printer.writeline("def %s(%s):" % (funcname, ",".join(namedecls)))
+        self.printer.writeline("return render_%s(%s)" % (funcname, ",".join(nameargs)))
+        self.printer.writeline(None)
+        
+    def write_inline_def(self, node, identifiers, nested):
+        """write a locally-available def callable inside an enclosing def."""
+        
+        namedecls = node.function_decl.get_argument_expressions()
+        
+        decorator = node.decorator
+        if decorator:
+            self.printer.writeline("@runtime._decorate_inline(context, %s)" % decorator)
+        self.printer.writeline("def %s(%s):" % (node.name, ",".join(namedecls)))
+        filtered = len(node.filter_args.args) > 0 
+        buffered = eval(node.attributes.get('buffered', 'False'))
+        cached = eval(node.attributes.get('cached', 'False'))
+        self.printer.writelines(
+            "context.caller_stack._push_frame()",
+            "try:"
+            )
+        if buffered or filtered or cached:
+            self.printer.writelines(
+                "context._push_buffer()",
+                )
+
+        identifiers = identifiers.branch(node, nested=nested)
+
+        self.write_variable_declares(identifiers)
+        
+        self.identifier_stack.append(identifiers)
+        for n in node.nodes:
+            n.accept_visitor(self)
+        self.identifier_stack.pop()
+        
+        self.write_def_finish(node, buffered, filtered, cached)
+        self.printer.writeline(None)
+        if cached:
+            self.write_cache_decorator(node, node.name, 
+                                        namedecls, False, identifiers, 
+                                        inline=True, toplevel=False)
+            
+    def write_def_finish(self, node, buffered, filtered, cached, callstack=True):
+        """write the end section of a rendering function, either outermost or inline.
+        
+        this takes into account if the rendering function was filtered, buffered, etc.
+        and closes the corresponding try: block if any, and writes code to retrieve 
+        captured content, apply filters, send proper return value."""
+        
+        if not buffered and not cached and not filtered:
+            self.printer.writeline("return ''")
+            if callstack:
+                self.printer.writelines(
+                    "finally:",
+                        "context.caller_stack._pop_frame()",
+                    None
+                )
+                
+        if buffered or filtered or cached:
+            if buffered or cached:
+                # in a caching scenario, don't try to get a writer
+                # from the context after popping; assume the caching
+                # implemenation might be using a context with no
+                # extra buffers
+                self.printer.writelines(
+                    "finally:",
+                        "__M_buf = context._pop_buffer()"
+                )
+            else:
+                self.printer.writelines(
+                    "finally:",
+                        "__M_buf, __M_writer = context._pop_buffer_and_writer()"
+                )
+                
+            if callstack:
+                self.printer.writeline("context.caller_stack._pop_frame()")
+                
+            s = "__M_buf.getvalue()"
+            if filtered:
+                s = self.create_filter_callable(node.filter_args.args, s, False)
+            self.printer.writeline(None)
+            if buffered and not cached:
+                s = self.create_filter_callable(self.compiler.buffer_filters, s, False)
+            if buffered or cached:
+                self.printer.writeline("return %s" % s)
+            else:
+                self.printer.writelines(
+                    "__M_writer(%s)" % s,
+                    "return ''"
+                )
+
+    def write_cache_decorator(self, node_or_pagetag, name, 
+                                    args, buffered, identifiers, 
+                                    inline=False, toplevel=False):
+        """write a post-function decorator to replace a rendering 
+            callable with a cached version of itself."""
+            
+        self.printer.writeline("__M_%s = %s" % (name, name))
+        cachekey = node_or_pagetag.parsed_attributes.get('cache_key', repr(name))
+        cacheargs = {}
+        for arg in (
+                        ('cache_type', 'type'), ('cache_dir', 'data_dir'), 
+                        ('cache_timeout', 'expiretime'), ('cache_url', 'url')):
+            val = node_or_pagetag.parsed_attributes.get(arg[0], None)
+            if val is not None:
+                if arg[1] == 'expiretime':
+                    cacheargs[arg[1]] = int(eval(val))
+                else:
+                    cacheargs[arg[1]] = val
+            else:
+                if self.compiler.pagetag is not None:
+                    val = self.compiler.pagetag.parsed_attributes.get(arg[0], None)
+                    if val is not None:
+                        if arg[1] == 'expiretime':
+                            cacheargs[arg[1]] == int(eval(val))
+                        else:
+                            cacheargs[arg[1]] = val
+        
+        self.printer.writeline("def %s(%s):" % (name, ','.join(args)))
+        
+        # form "arg1, arg2, arg3=arg3, arg4=arg4", etc.
+        pass_args = [
+                        '=' in a and "%s=%s" % ((a.split('=')[0],)*2) or a 
+                        for a in args
+                    ]
+
+        self.write_variable_declares(
+                            identifiers, 
+                            toplevel=toplevel, 
+                            limit=node_or_pagetag.undeclared_identifiers()
+                        )
+        if buffered:
+            s = "context.get('local')."\
+                "get_cached(%s, defname=%r, %screatefunc=lambda:__M_%s(%s))" % \
+                            (cachekey, name, 
+                            ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.items()]), 
+                            name, ','.join(pass_args))
+            # apply buffer_filters
+            s = self.create_filter_callable(self.compiler.buffer_filters, s, False)
+            self.printer.writelines("return " + s,None)
+        else:
+            self.printer.writelines(
+                    "__M_writer(context.get('local')."
+                    "get_cached(%s, defname=%r, %screatefunc=lambda:__M_%s(%s)))" % 
+                    (cachekey, name, 
+                    ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.items()]), 
+                    name, ','.join(pass_args)),
+                    "return ''",
+                None
+            )
+
+    def create_filter_callable(self, args, target, is_expression):
+        """write a filter-applying expression based on the filters 
+        present in the given filter names, adjusting for the global 
+        'default' filter aliases as needed."""
+        
+        def locate_encode(name):
+            if re.match(r'decode\..+', name):
+                return "filters." + name
+            elif self.compiler.disable_unicode:
+                return filters.NON_UNICODE_ESCAPES.get(name, name)
+            else:
+                return filters.DEFAULT_ESCAPES.get(name, name)
+        
+        if 'n' not in args:
+            if is_expression:
+                if self.compiler.pagetag:
+                    args = self.compiler.pagetag.filter_args.args + args
+                if self.compiler.default_filters:
+                    args = self.compiler.default_filters + args
+        for e in args:
+            # if filter given as a function, get just the identifier portion
+            if e == 'n':
+                continue
+            m = re.match(r'(.+?)(\(.*\))', e)
+            if m:
+                (ident, fargs) = m.group(1,2)
+                f = locate_encode(ident)
+                e = f + fargs
+            else:
+                x = e
+                e = locate_encode(e)
+                assert e is not None
+            target = "%s(%s)" % (e, target)
+        return target
+        
+    def visitExpression(self, node):
+        self.write_source_comment(node)
+        if len(node.escapes) or \
+                (
+                    self.compiler.pagetag is not None and
+                    len(self.compiler.pagetag.filter_args.args)
+                ) or \
+                len(self.compiler.default_filters):
+                
+            s = self.create_filter_callable(node.escapes_code.args, "%s" % node.text, True)
+            self.printer.writeline("__M_writer(%s)" % s)
+        else:
+            self.printer.writeline("__M_writer(%s)" % node.text)
+            
+    def visitControlLine(self, node):
+        if node.isend:
+            if not node.get_children():
+                self.printer.writeline("pass")
+            self.printer.writeline(None)
+        else:
+            self.write_source_comment(node)
+            self.printer.writeline(node.text)
+            
+    def visitText(self, node):
+        self.write_source_comment(node)
+        self.printer.writeline("__M_writer(%s)" % repr(node.content))
+        
+    def visitTextTag(self, node):
+        filtered = len(node.filter_args.args) > 0
+        if filtered:
+            self.printer.writelines(
+                "__M_writer = context._push_writer()",
+                "try:",
+            )
+        for n in node.nodes:
+            n.accept_visitor(self)
+        if filtered:
+            self.printer.writelines(
+                "finally:",
+                "__M_buf, __M_writer = context._pop_buffer_and_writer()",
+                "__M_writer(%s)" % 
+                self.create_filter_callable(
+                                node.filter_args.args, 
+                                "__M_buf.getvalue()", 
+                                False),
+                None
+                )
+        
+    def visitCode(self, node):
+        if not node.ismodule:
+            self.write_source_comment(node)
+            self.printer.write_indented_block(node.text)
+
+            if not self.in_def and len(self.identifiers.locally_assigned) > 0:
+                # if we are the "template" def, fudge locally 
+                # declared/modified variables into the "__M_locals" dictionary,
+                # which is used for def calls within the same template, 
+                # to simulate "enclosing scope"
+                self.printer.writeline('__M_locals_builtin_stored = __M_locals_builtin()')
+                self.printer.writeline(
+                            '__M_locals.update(__M_dict_builtin([(__M_key,'
+                            ' __M_locals_builtin_stored[__M_key]) for '
+                            '__M_key in [%s] if __M_key in __M_locals_builtin_stored]))' %
+                            ','.join([repr(x) for x in node.declared_identifiers()]))
+
+    def visitIncludeTag(self, node):
+        self.write_source_comment(node)
+        args = node.attributes.get('args')
+        if args:
+            self.printer.writeline(
+                        "runtime._include_file(context, %s, _template_uri, %s)" %
+                        (node.parsed_attributes['file'], args))
+        else:
+            self.printer.writeline(
+                        "runtime._include_file(context, %s, _template_uri)" %
+                        (node.parsed_attributes['file']))
+            
+    def visitNamespaceTag(self, node):
+        pass
+            
+    def visitDefTag(self, node):
+        pass
+
+    def visitCallNamespaceTag(self, node):
+        # TODO: we can put namespace-specific checks here, such
+        # as ensure the given namespace will be imported,
+        # pre-import the namespace, etc.
+        self.visitCallTag(node)
+        
+    def visitCallTag(self, node):
+        self.printer.writeline("def ccall(caller):")
+        export = ['body']
+        callable_identifiers = self.identifiers.branch(node, nested=True)
+        body_identifiers = callable_identifiers.branch(node, nested=False)
+        # we want the 'caller' passed to ccall to be used 
+        # for the body() function, but for other non-body() 
+        # <%def>s within <%call> we want the current caller 
+        # off the call stack (if any)
+        body_identifiers.add_declared('caller')
+        
+        self.identifier_stack.append(body_identifiers)
+        class DefVisitor(object):
+            def visitDefTag(s, node):
+                self.write_inline_def(node, callable_identifiers, nested=False)
+                export.append(node.name)
+                # remove defs that are within the <%call> from the "closuredefs" defined
+                # in the body, so they dont render twice
+                if node.name in body_identifiers.closuredefs:
+                    del body_identifiers.closuredefs[node.name]
+
+        vis = DefVisitor()
+        for n in node.nodes:
+            n.accept_visitor(vis)
+        self.identifier_stack.pop()
+        
+        bodyargs = node.body_decl.get_argument_expressions()    
+        self.printer.writeline("def body(%s):" % ','.join(bodyargs))
+        
+        # TODO: figure out best way to specify 
+        # buffering/nonbuffering (at call time would be better)
+        buffered = False
+        if buffered:
+            self.printer.writelines(
+                "context._push_buffer()",
+                "try:"
+            )
+        self.write_variable_declares(body_identifiers)
+        self.identifier_stack.append(body_identifiers)
+        
+        for n in node.nodes:
+            n.accept_visitor(self)
+        self.identifier_stack.pop()
+        
+        self.write_def_finish(node, buffered, False, False, callstack=False)
+        self.printer.writelines(
+            None,
+            "return [%s]" % (','.join(export)),
+            None
+        )
+
+        self.printer.writelines(
+            # get local reference to current caller, if any
+            "caller = context.caller_stack._get_caller()",
+            # push on caller for nested call
+            "context.caller_stack.nextcaller = "
+                "runtime.Namespace('caller', context, callables=ccall(caller))",
+            "try:")
+        self.write_source_comment(node)
+        self.printer.writelines(
+                "__M_writer(%s)" % self.create_filter_callable([], node.expression, True),
+            "finally:",
+                "context.caller_stack.nextcaller = None",
+            None
+        )
+
+class _Identifiers(object):
+    """tracks the status of identifier names as template code is rendered."""
+    
+    def __init__(self, node=None, parent=None, nested=False):
+            
+        if parent is not None:
+            # if we are the branch created in write_namespaces(),
+            # we don't share any context from the main body().
+            if isinstance(node, parsetree.NamespaceTag):
+                self.declared = set()
+                self.topleveldefs = util.SetLikeDict()
+            else:
+                # things that have already been declared 
+                # in an enclosing namespace (i.e. names we can just use)
+                self.declared = set(parent.declared).\
+                                        union([c.name for c in list(parent.closuredefs.values())]).\
+                                        union(parent.locally_declared).\
+                                        union(parent.argument_declared)
+            
+                # if these identifiers correspond to a "nested" 
+                # scope, it means whatever the parent identifiers 
+                # had as undeclared will have been declared by that parent, 
+                # and therefore we have them in our scope.
+                if nested:
+                    self.declared = self.declared.union(parent.undeclared)
+            
+                # top level defs that are available
+                self.topleveldefs = util.SetLikeDict(**parent.topleveldefs)
+        else:
+            self.declared = set()
+            self.topleveldefs = util.SetLikeDict()
+        
+        # things within this level that are referenced before they 
+        # are declared (e.g. assigned to)
+        self.undeclared = set()
+        
+        # things that are declared locally.  some of these things 
+        # could be in the "undeclared" list as well if they are 
+        # referenced before declared
+        self.locally_declared = set()
+    
+        # assignments made in explicit python blocks.  
+        # these will be propagated to 
+        # the context of local def calls.
+        self.locally_assigned = set()
+        
+        # things that are declared in the argument 
+        # signature of the def callable
+        self.argument_declared = set()
+        
+        # closure defs that are defined in this level
+        self.closuredefs = util.SetLikeDict()
+        
+        self.node = node
+        
+        if node is not None:
+            node.accept_visitor(self)
+        
+    def branch(self, node, **kwargs):
+        """create a new Identifiers for a new Node, with 
+          this Identifiers as the parent."""
+          
+        return _Identifiers(node, self, **kwargs)
+    
+    @property
+    def defs(self):
+        return set(self.topleveldefs.union(self.closuredefs).values())
+    
+    def __repr__(self):
+        return "Identifiers(declared=%r, locally_declared=%r, "\
+                "undeclared=%r, topleveldefs=%r, closuredefs=%r, argumentdeclared=%r)" %\
+                (
+                    list(self.declared),
+                    list(self.locally_declared),
+                    list(self.undeclared),
+                    [c.name for c in list(self.topleveldefs.values())],
+                    [c.name for c in list(self.closuredefs.values())],
+                    self.argument_declared)
+        
+    def check_declared(self, node):
+        """update the state of this Identifiers with the undeclared 
+            and declared identifiers of the given node."""
+        
+        for ident in node.undeclared_identifiers():
+            if ident != 'context' and ident not in self.declared.union(self.locally_declared):
+                self.undeclared.add(ident)
+        for ident in node.declared_identifiers():
+            self.locally_declared.add(ident)
+    
+    def add_declared(self, ident):
+        self.declared.add(ident)
+        if ident in self.undeclared:
+            self.undeclared.remove(ident)
+                        
+    def visitExpression(self, node):
+        self.check_declared(node)
+        
+    def visitControlLine(self, node):
+        self.check_declared(node)
+        
+    def visitCode(self, node):
+        if not node.ismodule:
+            self.check_declared(node)
+            self.locally_assigned = self.locally_assigned.union(node.declared_identifiers())
+    
+    def visitNamespaceTag(self, node):
+        # only traverse into the sub-elements of a 
+        # <%namespace> tag if we are the branch created in 
+        # write_namespaces()
+        if self.node is node:
+            for n in node.nodes:
+                n.accept_visitor(self)
+            
+    def visitDefTag(self, node):
+        if node.is_root():
+            self.topleveldefs[node.name] = node
+        elif node is not self.node:
+            self.closuredefs[node.name] = node
+
+        for ident in node.undeclared_identifiers():
+            if ident != 'context' and ident not in self.declared.union(self.locally_declared):
+                self.undeclared.add(ident)
+                
+        # visit defs only one level deep
+        if node is self.node:
+            for ident in node.declared_identifiers():
+                self.argument_declared.add(ident)
+            for n in node.nodes:
+                n.accept_visitor(self)
+                
+    def visitIncludeTag(self, node):
+        self.check_declared(node)
+        
+    def visitPageTag(self, node):
+        for ident in node.declared_identifiers():
+            self.argument_declared.add(ident)
+        self.check_declared(node)
+    
+    def visitCallNamespaceTag(self, node):
+        self.visitCallTag(node)
+        
+    def visitCallTag(self, node):
+        if node is self.node:
+            for ident in node.undeclared_identifiers():
+                if ident != 'context' and ident not in self.declared.union(self.locally_declared):
+                    self.undeclared.add(ident)
+            for ident in node.declared_identifiers():
+                self.argument_declared.add(ident)
+            for n in node.nodes:
+                n.accept_visitor(self)
+        else:
+            for ident in node.undeclared_identifiers():
+                if ident != 'context' and ident not in self.declared.union(self.locally_declared):
+                    self.undeclared.add(ident)
+                
diff --git a/lib3/mako-0.3.6/mako/exceptions.py b/lib3/mako-0.3.6/mako/exceptions.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/exceptions.py
@@ -0,0 +1,309 @@
+# exceptions.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""exception classes"""
+
+import traceback, sys, re
+from mako import util
+
+class MakoException(Exception):
+    pass
+
+class RuntimeException(MakoException):
+    pass
+
+def _format_filepos(lineno, pos, filename):
+    if filename is None:
+        return " at line: %d char: %d" % (lineno, pos)
+    else:
+        return " in file '%s' at line: %d char: %d" % (filename, lineno, pos)
+        
+        
+class CompileException(MakoException):
+    def __init__(self, message, source, lineno, pos, filename):
+        MakoException.__init__(self, message + _format_filepos(lineno, pos, filename))
+        self.lineno =lineno
+        self.pos = pos
+        self.filename = filename
+        self.source = source
+                    
+class SyntaxException(MakoException):
+    def __init__(self, message, source, lineno, pos, filename):
+        MakoException.__init__(self, message + _format_filepos(lineno, pos, filename))
+        self.lineno =lineno
+        self.pos = pos
+        self.filename = filename
+        self.source = source
+
+class UnsupportedError(MakoException):
+    """raised when a retired feature is used."""
+        
+class TemplateLookupException(MakoException):
+    pass
+
+class TopLevelLookupException(TemplateLookupException):
+    pass
+    
+class RichTraceback(object):
+    """Pulls the current exception from the sys traceback and extracts
+    Mako-specific template information.
+    
+    See the usage examples in :ref:`handling_exceptions`.
+    
+    """
+    def __init__(self, error=None, traceback=None):
+        self.source, self.lineno = "", 0
+
+        if error is None or traceback is None:
+            t, value, tback = sys.exc_info()
+        
+        if error is None:
+            error = value or t
+            
+        if traceback is None:
+            traceback = tback
+            
+        self.error = error
+        self.records = self._init(traceback)
+            
+        if isinstance(self.error, (CompileException, SyntaxException)):
+            import mako.template
+            self.source = self.error.source
+            self.lineno = self.error.lineno
+            self._has_source = True
+            
+        self._init_message()
+    
+    @property
+    def errorname(self):
+        return util.exception_name(self.error)
+        
+    def _init_message(self):
+        """Find a unicode representation of self.error"""
+        try:
+            self.message = str(self.error)
+        except UnicodeError:
+            try:
+                self.message = str(self.error)
+            except UnicodeEncodeError:
+                # Fallback to args as neither unicode nor
+                # str(Exception(u'\xe6')) work in Python < 2.6
+                self.message = self.error.args[0]
+        if not isinstance(self.message, str):
+            self.message = str(self.message, 'ascii', 'replace')
+
+    def _get_reformatted_records(self, records):
+        for rec in records:
+            if rec[6] is not None:
+                yield (rec[4], rec[5], rec[2], rec[6])
+            else:
+                yield tuple(rec[0:4])
+                
+    @property
+    def traceback(self):
+        """return a list of 4-tuple traceback records (i.e. normal python
+        format) with template-corresponding lines remapped to the originating
+        template.
+        
+        """
+        return list(self._get_reformatted_records(self.records))
+    
+    @property
+    def reverse_records(self):
+        return reversed(self.records)
+        
+    @property
+    def reverse_traceback(self):
+        """return the same data as traceback, except in reverse order.
+        """
+        
+        return list(self._get_reformatted_records(self.reverse_records))
+
+    def _init(self, trcback):
+        """format a traceback from sys.exc_info() into 7-item tuples,
+        containing the regular four traceback tuple items, plus the original
+        template filename, the line number adjusted relative to the template
+        source, and code line from that line number of the template."""
+
+        import mako.template
+        mods = {}
+        rawrecords = traceback.extract_tb(trcback)
+        new_trcback = []
+        for filename, lineno, function, line in rawrecords:
+            if not line:
+                line = ''
+            try:
+                (line_map, template_lines) = mods[filename]
+            except KeyError:
+                try:
+                    info = mako.template._get_module_info(filename)
+                    module_source = info.code
+                    template_source = info.source
+                    template_filename = info.template_filename or filename
+                except KeyError:
+                    # A normal .py file (not a Template)
+                    if not util.py3k:
+                        try:
+                            fp = open(filename, 'rb')
+                            encoding = util.parse_encoding(fp)
+                            fp.close()
+                        except IOError:
+                            encoding = None
+                        if encoding:
+                            line = line.decode(encoding)
+                        else:
+                            line = line.decode('ascii', 'replace')
+                    new_trcback.append((filename, lineno, function, line, 
+                                            None, None, None, None))
+                    continue
+
+                template_ln = module_ln = 1
+                line_map = {}
+                for line in module_source.split("\n"):
+                    match = re.match(r'\s*# SOURCE LINE (\d+)', line)
+                    if match:
+                        template_ln = int(match.group(1))
+                    else:
+                        template_ln += 1
+                    module_ln += 1
+                    line_map[module_ln] = template_ln
+                template_lines = [line for line in
+                                    template_source.split("\n")]
+                mods[filename] = (line_map, template_lines)
+
+            template_ln = line_map[lineno]
+            if template_ln <= len(template_lines):
+                template_line = template_lines[template_ln - 1]
+            else:
+                template_line = None
+            new_trcback.append((filename, lineno, function, 
+                                line, template_filename, template_ln, 
+                                template_line, template_source))
+        if not self.source:
+            for l in range(len(new_trcback)-1, 0, -1):
+                if new_trcback[l][5]:
+                    self.source = new_trcback[l][7]
+                    self.lineno = new_trcback[l][5]
+                    break
+            else:
+                if new_trcback:
+                    try:
+                        # A normal .py file (not a Template)
+                        fp = open(new_trcback[-1][0], 'rb')
+                        encoding = util.parse_encoding(fp)
+                        fp.seek(0)
+                        self.source = fp.read()
+                        fp.close()
+                        if encoding:
+                            self.source = self.source.decode(encoding)
+                    except IOError:
+                        self.source = ''
+                    self.lineno = new_trcback[-1][1]
+        return new_trcback
+
+                
+def text_error_template(lookup=None):
+    """Provides a template that renders a stack trace in a similar format to
+    the Python interpreter, substituting source template filenames, line
+    numbers and code for that of the originating source template, as
+    applicable.
+    
+    """
+    import mako.template
+    return mako.template.Template(r"""
+<%page args="error=None, traceback=None"/>
+<%!
+    from mako.exceptions import RichTraceback
+%>\
+<%
+    tback = RichTraceback(error=error, traceback=traceback)
+%>\
+Traceback (most recent call last):
+% for (filename, lineno, function, line) in tback.traceback:
+  File "${filename}", line ${lineno}, in ${function or '?'}
+    ${line | trim}
+% endfor
+${tback.errorname}: ${tback.message}
+""")
+
+def html_error_template():
+    """Provides a template that renders a stack trace in an HTML format,
+    providing an excerpt of code as well as substituting source template
+    filenames, line numbers and code for that of the originating source
+    template, as applicable.
+
+    The template's default encoding_errors value is 'htmlentityreplace'. the
+    template has two options. With the full option disabled, only a section of
+    an HTML document is returned. with the css option disabled, the default
+    stylesheet won't be included.
+    
+    """
+    import mako.template
+    return mako.template.Template(r"""
+<%!
+    from mako.exceptions import RichTraceback
+%>
+<%page args="full=True, css=True, error=None, traceback=None"/>
+% if full:
+<html>
+<head>
+    <title>Mako Runtime Error</title>
+% endif
+% if css:
+    <style>
+        body { font-family:verdana; margin:10px 30px 10px 30px;}
+        .stacktrace { margin:5px 5px 5px 5px; }
+        .highlight { padding:0px 10px 0px 10px; background-color:#9F9FDF; }
+        .nonhighlight { padding:0px; background-color:#DFDFDF; }
+        .sample { padding:10px; margin:10px 10px 10px 10px; font-family:monospace; }
+        .sampleline { padding:0px 10px 0px 10px; }
+        .sourceline { margin:5px 5px 10px 5px; font-family:monospace;}
+        .location { font-size:80%; }
+    </style>
+% endif
+% if full:
+</head>
+<body>
+% endif
+
+<h2>Error !</h2>
+<%
+    tback = RichTraceback(error=error, traceback=traceback)
+    src = tback.source
+    line = tback.lineno
+    if src:
+        lines = src.split('\n')
+    else:
+        lines = None
+%>
+<h3>${tback.errorname}: ${tback.message}</h3>
+
+% if lines:
+    <div class="sample">
+    <div class="nonhighlight">
+% for index in range(max(0, line-4),min(len(lines), line+5)):
+    % if index + 1 == line:
+<div class="highlight">${index + 1} ${lines[index] | h}</div>
+    % else:
+<div class="sampleline">${index + 1} ${lines[index] | h}</div>
+    % endif
+% endfor
+    </div>
+    </div>
+% endif
+
+<div class="stacktrace">
+% for (filename, lineno, function, line) in tback.reverse_traceback:
+    <div class="location">${filename}, line ${lineno}:</div>
+    <div class="sourceline">${line | h}</div>
+% endfor
+</div>
+
+% if full:
+</body>
+</html>
+% endif
+""", output_encoding=sys.getdefaultencoding(), encoding_errors='htmlentityreplace')
diff --git a/lib3/mako-0.3.6/mako/ext/autohandler.py b/lib3/mako-0.3.6/mako/ext/autohandler.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/ext/autohandler.py
@@ -0,0 +1,59 @@
+"""adds autohandler functionality to Mako templates.
+
+requires that the TemplateLookup class is used with templates.
+
+usage:
+
+<%!
+    from mako.ext.autohandler import autohandler
+%>
+<%inherit file="${autohandler(template, context)}"/>
+
+
+or with custom autohandler filename:
+
+<%!
+    from mako.ext.autohandler import autohandler
+%>
+<%inherit file="${autohandler(template, context, name='somefilename')}"/>
+
+"""
+
+import posixpath, os, re
+
+def autohandler(template, context, name='autohandler'):
+    lookup = context.lookup
+    _template_uri = template.module._template_uri
+    if not lookup.filesystem_checks:
+        try:
+            return lookup._uri_cache[(autohandler, _template_uri, name)]
+        except KeyError:
+            pass
+
+    tokens = re.findall(r'([^/]+)', posixpath.dirname(_template_uri)) + [name]
+    while len(tokens):
+        path = '/' + '/'.join(tokens)
+        if path != _template_uri and _file_exists(lookup, path):
+            if not lookup.filesystem_checks:
+                return lookup._uri_cache.setdefault(
+                            (autohandler, _template_uri, name), path)
+            else:
+                return path
+        if len(tokens) == 1:
+            break
+        tokens[-2:] = [name]
+        
+    if not lookup.filesystem_checks:
+        return lookup._uri_cache.setdefault(
+                            (autohandler, _template_uri, name), None)
+    else:
+        return None
+
+def _file_exists(lookup, path):
+    psub = re.sub(r'^/', '',path)
+    for d in lookup.directories:
+        if os.path.exists(d + '/' + psub):
+            return True
+    else:
+        return False
+    
diff --git a/lib3/mako-0.3.6/mako/ext/babelplugin.py b/lib3/mako-0.3.6/mako/ext/babelplugin.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/ext/babelplugin.py
@@ -0,0 +1,123 @@
+"""gettext message extraction via Babel: http://babel.edgewall.org/"""
+from io import StringIO
+
+from babel.messages.extract import extract_python
+
+from mako import lexer, parsetree
+
+def extract(fileobj, keywords, comment_tags, options):
+    """Extract messages from Mako templates.
+
+    :param fileobj: the file-like object the messages should be extracted from
+    :param keywords: a list of keywords (i.e. function names) that should be
+                     recognized as translation functions
+    :param comment_tags: a list of translator tags to search for and include
+                         in the results
+    :param options: a dictionary of additional options (optional)
+    :return: an iterator over ``(lineno, funcname, message, comments)`` tuples
+    :rtype: ``iterator``
+    """
+    encoding = options.get('input_encoding', options.get('encoding', None))
+
+    template_node = lexer.Lexer(fileobj.read(),
+                                input_encoding=encoding).parse()
+    for extracted in extract_nodes(template_node.get_children(),
+                                   keywords, comment_tags, options):
+        yield extracted
+
+def extract_nodes(nodes, keywords, comment_tags, options):
+    """Extract messages from Mako's lexer node objects
+
+    :param nodes: an iterable of Mako parsetree.Node objects to extract from
+    :param keywords: a list of keywords (i.e. function names) that should be
+                     recognized as translation functions
+    :param comment_tags: a list of translator tags to search for and include
+                         in the results
+    :param options: a dictionary of additional options (optional)
+    :return: an iterator over ``(lineno, funcname, message, comments)`` tuples
+    :rtype: ``iterator``
+    """
+    translator_comments = []
+    in_translator_comments = False
+
+    for node in nodes:
+        child_nodes = None
+        if in_translator_comments and isinstance(node, parsetree.Text) and \
+                not node.content.strip():
+            # Ignore whitespace within translator comments
+            continue
+
+        if isinstance(node, parsetree.Comment):
+            value = node.text.strip()
+            if in_translator_comments:
+                translator_comments.extend(_split_comment(node.lineno, value))
+                continue
+            for comment_tag in comment_tags:
+                if value.startswith(comment_tag):
+                    in_translator_comments = True
+                    translator_comments.extend(_split_comment(node.lineno,
+                                                              value))
+            continue
+
+        if isinstance(node, parsetree.DefTag):
+            code = node.function_decl.code
+            child_nodes = node.nodes
+        elif isinstance(node, parsetree.CallTag):
+            code = node.code.code
+            child_nodes = node.nodes
+        elif isinstance(node, parsetree.PageTag):
+            code = node.body_decl.code
+        elif isinstance(node, parsetree.CallNamespaceTag):
+            attribs = ', '.join(['%s=%s' % (key, val)
+                                 for key, val in node.attributes.items()])
+            code = '{%s}' % attribs
+            child_nodes = node.nodes
+        elif isinstance(node, parsetree.ControlLine):
+            if node.isend:
+                translator_comments = []
+                in_translator_comments = False
+                continue
+            code = node.text
+        elif isinstance(node, parsetree.Code):
+            # <% and <%! blocks would provide their own translator comments
+            translator_comments = []
+            in_translator_comments = False
+
+            code = node.code.code
+        elif isinstance(node, parsetree.Expression):
+            code = node.code.code
+        else:
+            translator_comments = []
+            in_translator_comments = False
+            continue
+
+        # Comments don't apply unless they immediately preceed the message
+        if translator_comments and \
+                translator_comments[-1][0] < node.lineno - 1:
+            translator_comments = []
+        else:
+            translator_comments = \
+                [comment[1] for comment in translator_comments]
+
+        if isinstance(code, str):
+            code = code.encode('ascii', 'backslashreplace')
+        code = StringIO(code)
+        for lineno, funcname, messages, python_translator_comments \
+                in extract_python(code, keywords, comment_tags, options):
+            yield (node.lineno + (lineno - 1), funcname, messages,
+                   translator_comments + python_translator_comments)
+
+        translator_comments = []
+        in_translator_comments = False
+
+        if child_nodes:
+            for extracted in extract_nodes(child_nodes, keywords, comment_tags,
+                                           options):
+                yield extracted
+
+
+def _split_comment(lineno, comment):
+    """Return the multiline comment at lineno split into a list of comment line
+    numbers and the accompanying comment line"""
+    return [(lineno + index, line) for index, line in
+            enumerate(comment.splitlines())]
diff --git a/lib3/mako-0.3.6/mako/ext/preprocessors.py b/lib3/mako-0.3.6/mako/ext/preprocessors.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/ext/preprocessors.py
@@ -0,0 +1,14 @@
+"""preprocessing functions, used with the 'preprocessor' 
+argument on Template, TemplateLookup"""
+
+import re
+
+def convert_comments(text):
+    """preprocess old style comments.
+    
+    example:
+    
+    from mako.ext.preprocessors import convert_comments
+    t = Template(..., preprocessor=preprocess_comments)"""
+    return re.sub(r'(?<=\n)\s*#[^#]', "##", text)
+
diff --git a/lib3/mako-0.3.6/mako/ext/pygmentplugin.py b/lib3/mako-0.3.6/mako/ext/pygmentplugin.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/ext/pygmentplugin.py
@@ -0,0 +1,101 @@
+import re
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+from pygments.lexers.web import \
+     HtmlLexer, XmlLexer, JavascriptLexer, CssLexer
+from pygments.lexers.agile import PythonLexer
+from pygments.lexer import Lexer, DelegatingLexer, RegexLexer, bygroups, \
+     include, using, this
+from pygments.token import Error, Punctuation, \
+     Text, Comment, Operator, Keyword, Name, String, Number, Other, Literal
+from pygments.util import html_doctype_matches, looks_like_xml
+
+class MakoLexer(RegexLexer):
+    name = 'Mako'
+    aliases = ['mako']
+    filenames = ['*.mao']
+
+    tokens = {
+        'root': [
+            (r'(\s*)(\%)(\s*end(?:\w+))(\n|\Z)',
+             bygroups(Text, Comment.Preproc, Keyword, Other)),
+            (r'(\s*)(\%(?!%))([^\n]*)(\n|\Z)',
+             bygroups(Text, Comment.Preproc, using(PythonLexer), Other)),
+             (r'(\s*)(##[^\n]*)(\n|\Z)',
+              bygroups(Text, Comment.Preproc, Other)),
+              (r'''(?s)<%doc>.*?</%doc>''', Comment.Preproc),
+            (r'(<%)([\w\.\:]+)', bygroups(Comment.Preproc, Name.Builtin), 'tag'),
+            (r'(</%)([\w\.\:]+)(>)', bygroups(Comment.Preproc, Name.Builtin, Comment.Preproc)),
+            (r'<%(?=([\w\.\:]+))', Comment.Preproc, 'ondeftags'),
+            (r'(<%(?:!?))(.*?)(%>)(?s)', bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)),
+            (r'(\$\{)(.*?)(\})',
+             bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc)),
+            (r'''(?sx)
+                (.+?)               # anything, followed by:
+                (?:
+                 (?<=\n)(?=%(?!%)|\#\#) |  # an eval or comment line
+                 (?=\#\*) |          # multiline comment
+                 (?=</?%) |         # a python block
+                                    # call start or end
+                 (?=\$\{) |         # a substitution
+                 (?<=\n)(?=\s*%) |
+                                    # - don't consume
+                 (\\\n) |           # an escaped newline
+                 \Z                 # end of string
+                )
+            ''', bygroups(Other, Operator)),
+            (r'\s+', Text),
+        ],
+        'ondeftags': [
+            (r'<%', Comment.Preproc),
+            (r'(?<=<%)(include|inherit|namespace|page)', Name.Builtin),
+            include('tag'),
+        ],
+        'tag': [
+            (r'((?:\w+)\s*=)\s*(".*?")',
+             bygroups(Name.Attribute, String)),
+            (r'/?\s*>', Comment.Preproc, '#pop'),
+            (r'\s+', Text),
+        ],
+        'attr': [
+            ('".*?"', String, '#pop'),
+            ("'.*?'", String, '#pop'),
+            (r'[^\s>]+', String, '#pop'),
+        ],
+    }
+
+
+class MakoHtmlLexer(DelegatingLexer):
+    name = 'HTML+Mako'
+    aliases = ['html+mako']
+
+    def __init__(self, **options):
+        super(MakoHtmlLexer, self).__init__(HtmlLexer, MakoLexer,
+                                              **options)
+
+class MakoXmlLexer(DelegatingLexer):
+    name = 'XML+Mako'
+    aliases = ['xml+mako']
+
+    def __init__(self, **options):
+        super(MakoXmlLexer, self).__init__(XmlLexer, MakoLexer,
+                                             **options)
+
+class MakoJavascriptLexer(DelegatingLexer):
+    name = 'JavaScript+Mako'
+    aliases = ['js+mako', 'javascript+mako']
+
+    def __init__(self, **options):
+        super(MakoJavascriptLexer, self).__init__(JavascriptLexer,
+                                                    MakoLexer, **options)
+
+class MakoCssLexer(DelegatingLexer):
+    name = 'CSS+Mako'
+    aliases = ['css+mako']
+
+    def __init__(self, **options):
+        super(MakoCssLexer, self).__init__(CssLexer, MakoLexer,
+                                             **options)
diff --git a/lib3/mako-0.3.6/mako/ext/turbogears.py b/lib3/mako-0.3.6/mako/ext/turbogears.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/ext/turbogears.py
@@ -0,0 +1,50 @@
+import re, inspect
+from mako.lookup import TemplateLookup
+from mako.template import Template
+
+class TGPlugin(object):
+    """TurboGears compatible Template Plugin."""
+
+    def __init__(self, extra_vars_func=None, options=None, extension='mak'):
+        self.extra_vars_func = extra_vars_func
+        self.extension = extension
+        if not options:
+            options = {}
+
+        # Pull the options out and initialize the lookup
+        lookup_options = {}
+        for k, v in options.items():
+            if k.startswith('mako.'):
+                lookup_options[k[5:]] = v
+            elif k in ['directories', 'filesystem_checks', 'module_directory']:
+                lookup_options[k] = v
+        self.lookup = TemplateLookup(**lookup_options)
+        
+        self.tmpl_options = {}
+        # transfer lookup args to template args, based on those available
+        # in getargspec
+        for kw in inspect.getargspec(Template.__init__)[0]:
+            if kw in lookup_options:
+                self.tmpl_options[kw] = lookup_options[kw]
+
+    def load_template(self, templatename, template_string=None):
+        """Loads a template from a file or a string"""
+        if template_string is not None:
+            return Template(template_string, **self.tmpl_options)
+        # Translate TG dot notation to normal / template path
+        if '/' not in templatename:
+            templatename = '/' + templatename.replace('.', '/') + '.' + self.extension
+
+        # Lookup template
+        return self.lookup.get_template(templatename)
+
+    def render(self, info, format="html", fragment=False, template=None):
+        if isinstance(template, str):
+            template = self.load_template(template)
+
+        # Load extra vars func if provided
+        if self.extra_vars_func:
+            info.update(self.extra_vars_func())
+
+        return template.render(**info)
+
diff --git a/lib3/mako-0.3.6/mako/filters.py b/lib3/mako-0.3.6/mako/filters.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/filters.py
@@ -0,0 +1,189 @@
+# filters.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Geoffrey T. Dairiki <dairiki at dairiki.org> and Michael Bayer <mike_mp at zzzcomputing.com>
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+
+import re, urllib.request, urllib.parse, urllib.error, html.entities, codecs
+from io import StringIO
+from mako import util
+
+xml_escapes = {
+    '&' : '&',
+    '>' : '>', 
+    '<' : '<', 
+    '"' : '"',   # also " in html-only
+    "'" : '''    # also ' in html-only    
+}
+
+# XXX: " is valid in HTML and XML
+#      ' is not valid HTML, but is valid XML
+
+def legacy_html_escape(string):
+    """legacy HTML escape for non-unicode mode."""
+
+    return re.sub(r'([&<"\'>])', lambda m: xml_escapes[m.group()], string)
+
+try:
+    import markupsafe
+    def html_escape(string):
+        return markupsafe.escape(string)
+except ImportError:
+    html_escape = legacy_html_escape
+
+    
+def xml_escape(string):
+    return re.sub(r'([&<"\'>])', lambda m: xml_escapes[m.group()], string)
+
+def url_escape(string):
+    # convert into a list of octets
+    string = string.encode("utf8")
+    return urllib.parse.quote_plus(string)
+
+def url_unescape(string):
+    text = urllib.parse.unquote_plus(string)
+    if not is_ascii_str(text):
+        text = text.decode("utf8")
+    return text
+
+def trim(string):
+    return string.strip()
+
+
+class Decode(object):
+    def __getattr__(self, key):
+        def decode(x):
+            if isinstance(x, str):
+                return x
+            elif not isinstance(x, str):
+                return str(str(x), encoding=key)
+            else:
+                return str(x, encoding=key)
+        return decode
+decode = Decode()
+        
+            
+_ASCII_re = re.compile(r'\A[\x00-\x7f]*\Z')
+
+def is_ascii_str(text):
+    return isinstance(text, str) and _ASCII_re.match(text)
+
+################################################################    
+
+class XMLEntityEscaper(object):
+    def __init__(self, codepoint2name, name2codepoint):
+        self.codepoint2entity = dict([(c, '&%s;' % n)
+                                      for c,n in codepoint2name.items()])
+        self.name2codepoint = name2codepoint
+
+    def escape_entities(self, text):
+        """Replace characters with their character entity references.
+
+        Only characters corresponding to a named entity are replaced.
+        """
+        return str(text).translate(self.codepoint2entity)
+
+    def __escape(self, m):
+        codepoint = ord(m.group())
+        try:
+            return self.codepoint2entity[codepoint]
+        except (KeyError, IndexError):
+            return '&#x%X;' % codepoint
+
+
+    __escapable = re.compile(r'["&<>]|[^\x00-\x7f]')
+
+    def escape(self, text):
+        """Replace characters with their character references.
+
+        Replace characters by their named entity references.
+        Non-ASCII characters, if they do not have a named entity reference,
+        are replaced by numerical character references.
+
+        The return value is guaranteed to be ASCII.
+        """
+        return self.__escapable.sub(self.__escape, str(text)
+                                    ).encode('ascii')
+
+    # XXX: This regexp will not match all valid XML entity names__.
+    # (It punts on details involving involving CombiningChars and Extenders.)
+    #
+    # .. __: http://www.w3.org/TR/2000/REC-xml-20001006#NT-EntityRef
+    __characterrefs = re.compile(r'''& (?:
+                                          \#(\d+)
+                                          | \#x([\da-f]+)
+                                          | ( (?!\d) [:\w] [-.:\w]+ )
+                                          ) ;''',
+                                 re.X | re.UNICODE)
+    
+    def __unescape(self, m):
+        dval, hval, name = m.groups()
+        if dval:
+            codepoint = int(dval)
+        elif hval:
+            codepoint = int(hval, 16)
+        else:
+            codepoint = self.name2codepoint.get(name, 0xfffd)
+            # U+FFFD = "REPLACEMENT CHARACTER"
+        if codepoint < 128:
+            return chr(codepoint)
+        return chr(codepoint)
+    
+    def unescape(self, text):
+        """Unescape character references.
+
+        All character references (both entity references and numerical
+        character references) are unescaped.
+        """
+        return self.__characterrefs.sub(self.__unescape, text)
+
+
+_html_entities_escaper = XMLEntityEscaper(html.entities.codepoint2name,
+                                          html.entities.name2codepoint)
+
+html_entities_escape = _html_entities_escaper.escape_entities
+html_entities_unescape = _html_entities_escaper.unescape
+
+
+def htmlentityreplace_errors(ex):
+    """An encoding error handler.
+
+    This python `codecs`_ error handler replaces unencodable
+    characters with HTML entities, or, if no HTML entity exists for
+    the character, XML character references.
+
+    >>> u'The cost was \u20ac12.'.encode('latin1', 'htmlentityreplace')
+    'The cost was €12.'
+    """
+    if isinstance(ex, UnicodeEncodeError):
+        # Handle encoding errors
+        bad_text = ex.object[ex.start:ex.end]
+        text = _html_entities_escaper.escape(bad_text)
+        return (str(text), ex.end)
+    raise ex
+
+codecs.register_error('htmlentityreplace', htmlentityreplace_errors)
+
+
+# TODO: options to make this dynamic per-compilation will be added in a later release
+DEFAULT_ESCAPES = {
+    'x':'filters.xml_escape',
+    'h':'filters.html_escape',
+    'u':'filters.url_escape',
+    'trim':'filters.trim',
+    'entity':'filters.html_entities_escape',
+    'unicode':'unicode',
+    'decode':'decode',
+    'str':'str',
+    'n':'n'
+}
+
+if util.py3k:
+    DEFAULT_ESCAPES.update({
+        'unicode':'str'
+    })
+
+NON_UNICODE_ESCAPES = DEFAULT_ESCAPES.copy()
+NON_UNICODE_ESCAPES['h'] = 'filters.legacy_html_escape'
+
diff --git a/lib3/mako-0.3.6/mako/lexer.py b/lib3/mako-0.3.6/mako/lexer.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/lexer.py
@@ -0,0 +1,415 @@
+# lexer.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""provides the Lexer class for parsing template strings into parse trees."""
+
+import re, codecs
+from mako import parsetree, exceptions, util
+from mako.pygen import adjust_whitespace
+
+_regexp_cache = {}
+
+class Lexer(object):
+    def __init__(self, text, filename=None, 
+                        disable_unicode=False, 
+                        input_encoding=None, preprocessor=None):
+        self.text = text
+        self.filename = filename
+        self.template = parsetree.TemplateNode(self.filename)
+        self.matched_lineno = 1
+        self.matched_charpos = 0
+        self.lineno = 1
+        self.match_position = 0
+        self.tag = []
+        self.control_line = []
+        self.disable_unicode = disable_unicode
+        self.encoding = input_encoding
+        
+        if util.py3k and disable_unicode:
+            raise exceptions.UnsupportedError(
+                                    "Mako for Python 3 does not "
+                                    "support disabling Unicode")
+        
+        if preprocessor is None:
+            self.preprocessor = []
+        elif not hasattr(preprocessor, '__iter__'):
+            self.preprocessor = [preprocessor]
+        else:
+            self.preprocessor = preprocessor
+    
+    @property
+    def exception_kwargs(self):
+        return {'source':self.text, 
+                'lineno':self.matched_lineno, 
+                'pos':self.matched_charpos, 
+                'filename':self.filename}
+    
+    def match(self, regexp, flags=None):
+        """compile the given regexp, cache the reg, and call match_reg()."""
+        
+        try:
+            reg = _regexp_cache[(regexp, flags)]
+        except KeyError:
+            if flags:
+                reg = re.compile(regexp, flags)
+            else:
+                reg = re.compile(regexp)
+            _regexp_cache[(regexp, flags)] = reg
+        
+        return self.match_reg(reg)
+        
+    def match_reg(self, reg):
+        """match the given regular expression object to the current text position.
+        
+        if a match occurs, update the current text and line position.
+        
+        """
+
+        mp = self.match_position
+
+        match = reg.match(self.text, self.match_position)
+        if match:
+            (start, end) = match.span()
+            if end == start:
+                self.match_position = end + 1
+            else:
+                self.match_position = end
+            self.matched_lineno = self.lineno
+            lines = re.findall(r"\n", self.text[mp:self.match_position])
+            cp = mp - 1
+            while (cp >= 0 and cp<self.textlength and self.text[cp] != '\n'):
+                cp -=1
+            self.matched_charpos = mp - cp
+            self.lineno += len(lines)
+            #print "MATCHED:", match.group(0), "LINE START:", 
+            # self.matched_lineno, "LINE END:", self.lineno
+        #print "MATCH:", regexp, "\n", self.text[mp : mp + 15], (match and "TRUE" or "FALSE")
+        return match
+    
+    def parse_until_text(self, *text):
+        startpos = self.match_position
+        while True:
+            match = self.match(r'#.*\n')
+            if match:
+                continue
+            match = self.match(r'(\"\"\"|\'\'\'|\"|\')')
+            if match:
+                m = self.match(r'.*?%s' % match.group(1), re.S)
+                if not m:
+                    raise exceptions.SyntaxException(
+                                "Unmatched '%s'" % 
+                                match.group(1), 
+                                **self.exception_kwargs)
+            else:
+                match = self.match(r'(%s)' % r'|'.join(text))
+                if match:
+                    return \
+                        self.text[startpos:self.match_position-len(match.group(1))],\
+                        match.group(1)
+                else:
+                    match = self.match(r".*?(?=\"|\'|#|%s)" % r'|'.join(text), re.S)
+                    if not match:
+                        raise exceptions.SyntaxException(
+                                    "Expected: %s" % 
+                                    ','.join(text), 
+                                    **self.exception_kwargs)
+                
+    def append_node(self, nodecls, *args, **kwargs):
+        kwargs.setdefault('source', self.text)
+        kwargs.setdefault('lineno', self.matched_lineno)
+        kwargs.setdefault('pos', self.matched_charpos)
+        kwargs['filename'] = self.filename
+        node = nodecls(*args, **kwargs)
+        if len(self.tag):
+            self.tag[-1].nodes.append(node)
+        else:
+            self.template.nodes.append(node)
+        if isinstance(node, parsetree.Tag):
+            if len(self.tag):
+                node.parent = self.tag[-1]
+            self.tag.append(node)
+        elif isinstance(node, parsetree.ControlLine):
+            if node.isend:
+                self.control_line.pop()
+            elif node.is_primary:
+                self.control_line.append(node)
+            elif len(self.control_line) and \
+                    not self.control_line[-1].is_ternary(node.keyword):
+                raise exceptions.SyntaxException(
+                                "Keyword '%s' not a legal ternary for keyword '%s'" %
+                                (node.keyword, self.control_line[-1].keyword),
+                                **self.exception_kwargs)
+
+    _coding_re = re.compile(r'#.*coding[:=]\s*([-\w.]+).*\r?\n')
+
+    def decode_raw_stream(self, text, decode_raw, known_encoding, filename):
+        """given string/unicode or bytes/string, determine encoding
+           from magic encoding comment, return body as unicode
+           or raw if decode_raw=False
+
+        """
+        if isinstance(text, str):
+            m = self._coding_re.match(text)
+            encoding = m and m.group(1) or known_encoding or 'ascii'
+            return encoding, text
+
+        if text.startswith(codecs.BOM_UTF8):
+            text = text[len(codecs.BOM_UTF8):]
+            parsed_encoding = 'utf-8'
+            m = self._coding_re.match(text.decode('utf-8', 'ignore'))
+            if m is not None and m.group(1) != 'utf-8':
+                raise exceptions.CompileException(
+                                "Found utf-8 BOM in file, with conflicting "
+                                "magic encoding comment of '%s'" % m.group(1), 
+                                text.decode('utf-8', 'ignore'), 
+                                0, 0, filename)
+        else:
+            m = self._coding_re.match(text.decode('utf-8', 'ignore'))
+            if m:
+                parsed_encoding = m.group(1)
+            else:
+                parsed_encoding = known_encoding or 'ascii'
+
+        if decode_raw:
+            try:
+                text = text.decode(parsed_encoding)
+            except UnicodeDecodeError as e:
+                raise exceptions.CompileException(
+                                "Unicode decode operation of encoding '%s' failed" %
+                                parsed_encoding, 
+                                text.decode('utf-8', 'ignore'), 
+                                0, 0, filename)
+
+        return parsed_encoding, text
+
+    def parse(self):
+        self.encoding, self.text = self.decode_raw_stream(self.text, 
+                                        not self.disable_unicode, 
+                                        self.encoding,
+                                        self.filename,)
+
+        for preproc in self.preprocessor:
+            self.text = preproc(self.text)
+        
+        # push the match marker past the 
+        # encoding comment.
+        self.match_reg(self._coding_re)
+        
+        self.textlength = len(self.text)
+            
+        while (True):
+            if self.match_position > self.textlength: 
+                break
+        
+            if self.match_end():
+                break
+            if self.match_expression():
+                continue
+            if self.match_control_line():
+                continue
+            if self.match_comment():
+                continue
+            if self.match_tag_start(): 
+                continue
+            if self.match_tag_end():
+                continue
+            if self.match_python_block():
+                continue
+            if self.match_text(): 
+                continue
+            
+            if self.match_position > self.textlength: 
+                break
+            raise exceptions.CompileException("assertion failed")
+            
+        if len(self.tag):
+            raise exceptions.SyntaxException("Unclosed tag: <%%%s>" % 
+                                                self.tag[-1].keyword, 
+                                                **self.exception_kwargs)
+        if len(self.control_line):
+            raise exceptions.SyntaxException("Unterminated control keyword: '%s'" %
+                                            self.control_line[-1].keyword, 
+                                            self.text, 
+                                            self.control_line[-1].lineno,
+                                            self.control_line[-1].pos, self.filename)
+        return self.template
+
+    def match_tag_start(self):
+        match = self.match(r'''
+            \<%     # opening tag
+            
+            ([\w\.\:]+)   # keyword
+            
+            ((?:\s+\w+|\s*=\s*|".*?"|'.*?')*)  # attrname, = sign, string expression
+            
+            \s*     # more whitespace
+            
+            (/)?>   # closing
+            
+            ''', 
+            
+            re.I | re.S | re.X)
+            
+        if match:
+            keyword, attr, isend = match.group(1), match.group(2), match.group(3)
+            self.keyword = keyword
+            attributes = {}
+            if attr:
+                for att in re.findall(r"\s*(\w+)\s*=\s*(?:'([^']*)'|\"([^\"]*)\")", attr):
+                    key, val1, val2 = att
+                    text = val1 or val2
+                    text = text.replace('\r\n', '\n')
+                    attributes[key] = text
+            self.append_node(parsetree.Tag, keyword, attributes)
+            if isend:
+                self.tag.pop()
+            else:
+                if keyword == 'text':
+                    match = self.match(r'(.*?)(?=\</%text>)',  re.S)
+                    if not match:
+                        raise exceptions.SyntaxException(
+                                            "Unclosed tag: <%%%s>" % 
+                                            self.tag[-1].keyword, 
+                                            **self.exception_kwargs)
+                    self.append_node(parsetree.Text, match.group(1))
+                    return self.match_tag_end()
+            return True
+        else: 
+            return False
+        
+    def match_tag_end(self):
+        match = self.match(r'\</%[\t ]*(.+?)[\t ]*>')
+        if match:
+            if not len(self.tag):
+                raise exceptions.SyntaxException(
+                                        "Closing tag without opening tag: </%%%s>" %
+                                        match.group(1), 
+                                        **self.exception_kwargs)
+            elif self.tag[-1].keyword != match.group(1):
+                raise exceptions.SyntaxException(
+                                        "Closing tag </%%%s> does not match tag: <%%%s>" %
+                                        (match.group(1), self.tag[-1].keyword),
+                                        **self.exception_kwargs)
+            self.tag.pop()
+            return True
+        else:
+            return False
+            
+    def match_end(self):
+        match = self.match(r'\Z', re.S)
+        if match:
+            string = match.group()
+            if string:
+                return string
+            else:
+                return True
+        else:
+            return False
+    
+    def match_text(self):
+        match = self.match(r"""
+                (.*?)         # anything, followed by:
+                (
+                 (?<=\n)(?=[ \t]*(?=%|\#\#)) # an eval or line-based 
+                                             # comment preceded by a 
+                                             # consumed newline and whitespace
+                 |
+                 (?=\${)      # an expression
+                 |
+                 (?=\#\*)     # multiline comment
+                 |
+                 (?=</?[%&])  # a substitution or block or call start or end
+                              # - don't consume
+                 |
+                 (\\\r?\n)    # an escaped newline  - throw away
+                 |
+                 \Z           # end of string
+                )""", re.X | re.S)
+        
+        if match:
+            text = match.group(1)
+            if text:
+                self.append_node(parsetree.Text, text)
+            return True
+        else:
+            return False
+    
+    def match_python_block(self):
+        match = self.match(r"<%(!)?")
+        if match:
+            line, pos = self.matched_lineno, self.matched_charpos
+            text, end = self.parse_until_text(r'%>')
+            # the trailing newline helps 
+            # compiler.parse() not complain about indentation
+            text = adjust_whitespace(text) + "\n"   
+            self.append_node(
+                            parsetree.Code, 
+                            text, 
+                            match.group(1)=='!', lineno=line, pos=pos)
+            return True
+        else:
+            return False
+            
+    def match_expression(self):
+        match = self.match(r"\${")
+        if match:
+            line, pos = self.matched_lineno, self.matched_charpos
+            text, end = self.parse_until_text(r'\|', r'}')
+            if end == '|':
+                escapes, end = self.parse_until_text(r'}')
+            else:
+                escapes = ""
+            text = text.replace('\r\n', '\n')
+            self.append_node(
+                            parsetree.Expression, 
+                            text, escapes.strip(), 
+                            lineno=line, pos=pos)
+            return True
+        else:
+            return False
+
+    def match_control_line(self):
+        match = self.match(r"(?<=^)[\t ]*(%(?!%)|##)[\t ]*((?:(?:\\r?\n)|[^\r\n])*)(?:\r?\n|\Z)", re.M)
+        if match:
+            operator = match.group(1)
+            text = match.group(2)
+            if operator == '%':
+                m2 = re.match(r'(end)?(\w+)\s*(.*)', text)
+                if not m2:
+                    raise exceptions.SyntaxException(
+                                "Invalid control line: '%s'" % 
+                                text, 
+                                **self.exception_kwargs)
+                isend, keyword = m2.group(1, 2)
+                isend = (isend is not None)
+                
+                if isend:
+                    if not len(self.control_line):
+                        raise exceptions.SyntaxException(
+                                "No starting keyword '%s' for '%s'" % 
+                                (keyword, text), 
+                                **self.exception_kwargs)
+                    elif self.control_line[-1].keyword != keyword:
+                        raise exceptions.SyntaxException(
+                                "Keyword '%s' doesn't match keyword '%s'" % 
+                                (text, self.control_line[-1].keyword), 
+                                **self.exception_kwargs)
+                self.append_node(parsetree.ControlLine, keyword, isend, text)
+            else:
+                self.append_node(parsetree.Comment, text)
+            return True
+        else:
+            return False
+
+    def match_comment(self):
+        """matches the multiline version of a comment"""
+        match = self.match(r"<%doc>(.*?)</%doc>", re.S)
+        if match:
+            self.append_node(parsetree.Comment, match.group(1))
+            return True
+        else:
+            return False
+             
diff --git a/lib3/mako-0.3.6/mako/lookup.py b/lib3/mako-0.3.6/mako/lookup.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/lookup.py
@@ -0,0 +1,321 @@
+# lookup.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer 
+# mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+import os, stat, posixpath, re
+from mako import exceptions, util
+from mako.template import Template
+
+try:
+    import threading
+except:
+    import dummy_threading as threading
+    
+class TemplateCollection(object):
+    """Represent a collection of :class:`.Template` objects, 
+    identifiable via uri.
+    
+    A :class:`.TemplateCollection` is linked to the usage of
+    all template tags that address other templates, such 
+    as ``<%include>``, ``<%namespace>``, and ``<%inherit>``.
+    The ``file`` attribute of each of those tags refers
+    to a string URI that is passed to that :class:`.Template`
+    object's :class:`.TemplateCollection` for resolution.
+    
+    :class:`.TemplateCollection` is an abstract class,
+    with the usual default implementation being :class:`.TemplateLookup`.
+    
+     """
+
+    def has_template(self, uri):
+        """Return ``True`` if this :class:`.TemplateLookup` is
+        capable of returning a :class:`.Template` object for the
+        given URL.
+
+        :param uri: String uri of the template to be resolved.
+        
+        """
+        try:
+            self.get_template(uri)
+            return True
+        except exceptions.TemplateLookupException:
+            return False
+
+    def get_template(self, uri, relativeto=None):
+        """Return a :class:`.Template` object corresponding to the given 
+        URL.
+        
+        The default implementation raises
+        :class:`.NotImplementedError`. Implementations should
+        raise :class:`.TemplateLookupException` if the given uri
+        cannot be resolved.
+        
+        :param uri: String uri of the template to be resolved.
+        :param relativeto: if present, the given URI is assumed to 
+         be relative to this uri.
+         
+        """
+        raise NotImplementedError()
+
+    def filename_to_uri(self, uri, filename):
+        """Convert the given filename to a uri relative to 
+           this TemplateCollection."""
+        
+        return uri
+        
+    def adjust_uri(self, uri, filename):
+        """Adjust the given uri based on the calling filename.
+        
+        When this method is called from the runtime, the
+        'filename' parameter is taken directly to the 'filename'
+        attribute of the calling template. Therefore a custom
+        TemplateCollection subclass can place any string
+        identifier desired in the "filename" parameter of the
+        Template objects it constructs and have them come back
+        here.
+        
+        """
+        return uri
+        
+class TemplateLookup(TemplateCollection):
+    """Represent a collection of templates that locates template source files
+    from the local filesystem.
+    
+    The primary argument is the ``directories`` argument, the list of
+    directories to search::
+    
+        lookup = TemplateLookup(["/path/to/templates"])
+        some_template = lookup.get_template("/index.html")
+        
+    The :class:`.TemplateLookup` can also be given :class:`.Template` objects
+    programatically using :meth:`.put_string` or :meth:`.put_template`::
+    
+        lookup = TemplateLookup()
+        lookup.put_string("base.html", '''
+            <html><body>${self.next()}</body></html>
+        ''')
+        lookup.put_string("hello.html", '''
+            <%include file='base.html'/>
+            
+            Hello, world !
+        ''')
+        
+    
+    :param directories: A list of directory names which will be 
+     searched for a particular template URI. The URI is appended
+     to each directory and the filesystem checked.
+    
+    :param collection_size: Approximate size of the collection used 
+     to store templates. If left at its default of -1, the size
+     is unbounded, and a plain Python dictionary is used to
+     relate URI strings to :class:`.Template` instances.
+     Otherwise, a least-recently-used cache object is used which
+     will maintain the size of the collection approximately to
+     the number given.
+     
+    :param filesystem_checks: When at its default value of ``True``, 
+     each call to :meth:`TemplateLookup.get_template()` will
+     compare the filesystem last modified time to the time in
+     which an existing :class:`.Template` object was created.
+     This allows the :class:`.TemplateLookup` to regenerate a
+     new :class:`.Template` whenever the original source has
+     been updated. Set this to ``False`` for a very minor
+     performance increase.
+    
+    :param modulename_callable: A callable which, when present, 
+     is passed the path of the source file as well as the
+     requested URI, and then returns the full path of the
+     generated Python module file. This is used to inject
+     alternate schemes for Pyhton module location. If left at
+     its default of ``None``, the built in system of generation
+     based on ``module_directory`` plus ``uri`` is used.
+     
+    All other keyword parameters available for
+    :class:`.Template` are mirrored here. When new
+    :class:`.Template` objects are created, the keywords
+    established with this :class:`.TemplateLookup` are passed on
+    to each new :class:`.Template`.
+    
+    """
+    
+    def __init__(self, 
+                        directories=None, 
+                        module_directory=None, 
+                        filesystem_checks=True, 
+                        collection_size=-1, 
+                        format_exceptions=False, 
+                        error_handler=None, 
+                        disable_unicode=False, 
+                        output_encoding=None, 
+                        encoding_errors='strict', 
+                        cache_type=None, 
+                        cache_dir=None, cache_url=None,
+                        cache_enabled=True, 
+                        modulename_callable=None, 
+                        default_filters=None, 
+                        buffer_filters=(), 
+                        strict_undefined=False,
+                        imports=None, 
+                        input_encoding=None, 
+                        preprocessor=None):
+                        
+        self.directories = [posixpath.normpath(d) for d in
+                            util.to_list(directories, ())
+                            ]
+        self.module_directory = module_directory
+        self.modulename_callable = modulename_callable
+        self.filesystem_checks = filesystem_checks
+        self.collection_size = collection_size
+
+        self.template_args = {
+            'format_exceptions':format_exceptions, 
+            'error_handler':error_handler, 
+            'disable_unicode':disable_unicode, 
+            'output_encoding':output_encoding, 
+            'encoding_errors':encoding_errors, 
+            'input_encoding':input_encoding, 
+            'module_directory':module_directory, 
+            'cache_type':cache_type, 
+            'cache_dir':cache_dir or module_directory, 
+            'cache_url':cache_url, 
+            'cache_enabled':cache_enabled, 
+            'default_filters':default_filters, 
+            'buffer_filters':buffer_filters,  
+            'strict_undefined':strict_undefined,
+            'imports':imports, 
+            'preprocessor':preprocessor}
+
+        if collection_size == -1:
+            self._collection = {}
+            self._uri_cache = {}
+        else:
+            self._collection = util.LRUCache(collection_size)
+            self._uri_cache = util.LRUCache(collection_size)
+        self._mutex = threading.Lock()
+        
+    def get_template(self, uri):
+        """Return a :class:`.Template` object corresponding to the given 
+        URL.
+        
+        Note the "relativeto" argument is not supported here at the moment.
+        
+        """
+        
+        try:
+            if self.filesystem_checks:
+                return self._check(uri, self._collection[uri])
+            else:
+                return self._collection[uri]
+        except KeyError:
+            u = re.sub(r'^\/+', '', uri)
+            for dir in self.directories:
+                srcfile = posixpath.normpath(posixpath.join(dir, u))
+                if os.path.isfile(srcfile):
+                    return self._load(srcfile, uri)
+            else:
+                raise exceptions.TopLevelLookupException(
+                                    "Cant locate template for uri %r" % uri)
+
+    def adjust_uri(self, uri, relativeto):
+        """adjust the given uri based on the given relative uri."""
+        
+        if uri[0] != '/':
+            if relativeto is not None:
+                return posixpath.join(posixpath.dirname(relativeto), uri)
+            else:
+                return '/' + uri
+        else:
+            return uri
+            
+    
+    def filename_to_uri(self, filename):
+        """Convert the given filename to a uri relative to 
+           this TemplateCollection."""
+
+        try:
+            return self._uri_cache[filename]
+        except KeyError:
+            value = self._relativeize(filename)
+            self._uri_cache[filename] = value
+            return value
+                    
+    def _relativeize(self, filename):
+        """Return the portion of a filename that is 'relative' 
+           to the directories in this lookup.
+           
+        """
+        
+        filename = posixpath.normpath(filename)
+        for dir in self.directories:
+            if filename[0:len(dir)] == dir:
+                return filename[len(dir):]
+        else:
+            return None
+            
+    def _load(self, filename, uri):
+        self._mutex.acquire()
+        try:
+            try:
+                # try returning from collection one 
+                # more time in case concurrent thread already loaded
+                return self._collection[uri]
+            except KeyError:
+                pass
+            try:
+                if self.modulename_callable is not None:
+                    module_filename = self.modulename_callable(filename, uri)
+                else:
+                    module_filename = None
+                self._collection[uri] = template = Template(
+                                        uri=uri,
+                                        filename=posixpath.normpath(filename),
+                                        lookup=self, 
+                                        module_filename=module_filename,
+                                        **self.template_args)
+                return template
+            except:
+                # if compilation fails etc, ensure 
+                # template is removed from collection,
+                # re-raise
+                self._collection.pop(uri, None)
+                raise
+        finally:
+            self._mutex.release()
+            
+    def _check(self, uri, template):
+        if template.filename is None:
+            return template
+        if not os.path.exists(template.filename):
+            self._collection.pop(uri, None)
+            raise exceptions.TemplateLookupException(
+                                "Cant locate template for uri %r" % uri)
+        elif template.module._modified_time < \
+                        os.stat(template.filename)[stat.ST_MTIME]:
+            self._collection.pop(uri, None)
+            return self._load(template.filename, uri)
+        else:
+            return template
+            
+    def put_string(self, uri, text):
+        """Place a new :class:`.Template` object into this
+        :class:`.TemplateLookup`, based on the given string of
+        text.
+        
+        """
+        self._collection[uri] = Template(
+                                    text, 
+                                    lookup=self, 
+                                    uri=uri, 
+                                    **self.template_args)
+        
+    def put_template(self, uri, template):
+        """Place a new :class:`.Template` object into this
+        :class:`.TemplateLookup`, based on the given
+        :class:`.Template` object.
+        
+        """
+        self._collection[uri] = template
+            
diff --git a/lib3/mako-0.3.6/mako/parsetree.py b/lib3/mako-0.3.6/mako/parsetree.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/parsetree.py
@@ -0,0 +1,497 @@
+# parsetree.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""defines the parse tree components for Mako templates."""
+
+from mako import exceptions, ast, util, filters
+import re
+
+class Node(object):
+    """base class for a Node in the parse tree."""
+    def __init__(self, source, lineno, pos, filename):
+        self.source = source
+        self.lineno = lineno
+        self.pos = pos
+        self.filename = filename
+        
+    @property
+    def exception_kwargs(self):
+        return {'source':self.source, 'lineno':self.lineno, 
+                'pos':self.pos, 'filename':self.filename}
+    
+    def get_children(self):
+        return []
+        
+    def accept_visitor(self, visitor):
+        def traverse(node):
+            for n in node.get_children():
+                n.accept_visitor(visitor)
+        method = getattr(visitor, "visit" + self.__class__.__name__, traverse)
+        method(self)
+
+class TemplateNode(Node):
+    """a 'container' node that stores the overall collection of nodes."""
+    
+    def __init__(self, filename):
+        super(TemplateNode, self).__init__('', 0, 0, filename)
+        self.nodes = []
+        self.page_attributes = {}
+        
+    def get_children(self):
+        return self.nodes
+        
+    def __repr__(self):
+        return "TemplateNode(%s, %r)" % (
+                    util.sorted_dict_repr(self.page_attributes), 
+                    self.nodes)
+        
+class ControlLine(Node):
+    """defines a control line, a line-oriented python line or end tag.
+    
+    e.g.::
+
+        % if foo:
+            (markup)
+        % endif
+    
+    """
+
+    def __init__(self, keyword, isend, text, **kwargs):
+        super(ControlLine, self).__init__(**kwargs)
+        self.text = text
+        self.keyword = keyword
+        self.isend = isend
+        self.is_primary = keyword in ['for','if', 'while', 'try']
+        if self.isend:
+            self._declared_identifiers = []
+            self._undeclared_identifiers = []
+        else:
+            code = ast.PythonFragment(text, **self.exception_kwargs)
+            self._declared_identifiers = code.declared_identifiers 
+            self._undeclared_identifiers = code.undeclared_identifiers
+
+    def declared_identifiers(self):
+        return self._declared_identifiers
+
+    def undeclared_identifiers(self):
+        return self._undeclared_identifiers
+        
+    def is_ternary(self, keyword):
+        """return true if the given keyword is a ternary keyword
+        for this ControlLine"""
+        
+        return keyword in {
+            'if':set(['else', 'elif']),
+            'try':set(['except', 'finally']),
+            'for':set(['else'])
+        }.get(self.keyword, [])
+        
+    def __repr__(self):
+        return "ControlLine(%r, %r, %r, %r)" % (
+            self.keyword, 
+            self.text, 
+            self.isend, 
+            (self.lineno, self.pos)
+        )
+
+class Text(Node):
+    """defines plain text in the template."""
+    
+    def __init__(self, content, **kwargs):
+        super(Text, self).__init__(**kwargs)
+        self.content = content
+        
+    def __repr__(self):
+        return "Text(%r, %r)" % (self.content, (self.lineno, self.pos))
+        
+class Code(Node):
+    """defines a Python code block, either inline or module level.
+    
+    e.g.::
+
+        inline:
+        <%
+            x = 12
+        %>
+    
+        module level:
+        <%!
+            import logger
+        %>
+    
+    """
+
+    def __init__(self, text, ismodule, **kwargs):
+        super(Code, self).__init__(**kwargs)
+        self.text = text
+        self.ismodule = ismodule
+        self.code = ast.PythonCode(text, **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return self.code.declared_identifiers
+
+    def undeclared_identifiers(self):
+        return self.code.undeclared_identifiers
+
+    def __repr__(self):
+        return "Code(%r, %r, %r)" % (
+            self.text, 
+            self.ismodule, 
+            (self.lineno, self.pos)
+        )
+        
+class Comment(Node):
+    """defines a comment line.
+    
+    # this is a comment
+    
+    """
+    
+    def __init__(self, text, **kwargs):
+        super(Comment, self).__init__(**kwargs)
+        self.text = text
+
+    def __repr__(self):
+        return "Comment(%r, %r)" % (self.text, (self.lineno, self.pos))
+        
+class Expression(Node):
+    """defines an inline expression.
+    
+    ${x+y}
+    
+    """
+    
+    def __init__(self, text, escapes, **kwargs):
+        super(Expression, self).__init__(**kwargs)
+        self.text = text
+        self.escapes = escapes
+        self.escapes_code = ast.ArgumentList(escapes, **self.exception_kwargs)
+        self.code = ast.PythonCode(text, **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return []
+
+    def undeclared_identifiers(self):
+        # TODO: make the "filter" shortcut list configurable at parse/gen time
+        return self.code.undeclared_identifiers.union(
+                self.escapes_code.undeclared_identifiers.difference(
+                    set(filters.DEFAULT_ESCAPES.keys())
+                )
+            ).difference(self.code.declared_identifiers)
+
+    def __repr__(self):
+        return "Expression(%r, %r, %r)" % (
+            self.text, 
+            self.escapes_code.args, 
+            (self.lineno, self.pos)
+        )
+        
+class _TagMeta(type):
+    """metaclass to allow Tag to produce a subclass according to
+    its keyword"""
+    
+    _classmap = {}
+    
+    def __init__(cls, clsname, bases, dict):
+        if cls.__keyword__ is not None:
+            cls._classmap[cls.__keyword__] = cls
+            super(_TagMeta, cls).__init__(clsname, bases, dict)
+            
+    def __call__(cls, keyword, attributes, **kwargs):
+        if ":" in keyword:
+            ns, defname = keyword.split(':')
+            return type.__call__(CallNamespaceTag, ns, defname, 
+                                        attributes, **kwargs)
+
+        try:
+            cls = _TagMeta._classmap[keyword]
+        except KeyError:
+            raise exceptions.CompileException(
+                "No such tag: '%s'" % keyword, 
+                source=kwargs['source'], 
+                lineno=kwargs['lineno'], 
+                pos=kwargs['pos'], 
+                filename=kwargs['filename']
+            )
+        return type.__call__(cls, keyword, attributes, **kwargs)
+        
+class Tag(Node, metaclass=_TagMeta):
+    """abstract base class for tags.
+    
+    <%sometag/>
+    
+    <%someothertag>
+        stuff
+    </%someothertag>
+    
+    """
+    __keyword__ = None
+    
+    def __init__(self, keyword, attributes, expressions, 
+                        nonexpressions, required, **kwargs):
+        """construct a new Tag instance.
+        
+        this constructor not called directly, and is only called
+        by subclasses.
+        
+        :param keyword: the tag keyword
+        
+        :param attributes: raw dictionary of attribute key/value pairs
+        
+        :param expressions: a set of identifiers that are legal attributes, 
+         which can also contain embedded expressions
+        
+        :param nonexpressions: a set of identifiers that are legal 
+         attributes, which cannot contain embedded expressions
+        
+        :param \**kwargs:
+         other arguments passed to the Node superclass (lineno, pos)
+        
+        """
+        super(Tag, self).__init__(**kwargs)
+        self.keyword = keyword
+        self.attributes = attributes
+        self._parse_attributes(expressions, nonexpressions)
+        missing = [r for r in required if r not in self.parsed_attributes]
+        if len(missing):
+            raise exceptions.CompileException(
+                "Missing attribute(s): %s" % 
+                    ",".join([repr(m) for m in missing]), 
+                **self.exception_kwargs)
+        self.parent = None
+        self.nodes = []
+        
+    def is_root(self):
+        return self.parent is None
+        
+    def get_children(self):
+        return self.nodes
+        
+    def _parse_attributes(self, expressions, nonexpressions):
+        undeclared_identifiers = set()
+        self.parsed_attributes = {}
+        for key in self.attributes:
+            if key in expressions:
+                expr = []
+                for x in re.compile(r'(\${.+?})',
+                                    re.S).split(self.attributes[key]):
+                    m = re.compile(r'^\${(.+?)}$', re.S).match(x)
+                    if m:
+                        code = ast.PythonCode(m.group(1).rstrip(),
+                                **self.exception_kwargs)
+                        # we aren't discarding "declared_identifiers" here,
+                        # which we do so that list comprehension-declared 
+                        # variables aren't counted.   As yet can't find a 
+                        # condition that requires it here.
+                        undeclared_identifiers = \
+                            undeclared_identifiers.union(
+                                    code.undeclared_identifiers)
+                        expr.append('(%s)' % m.group(1))
+                    else:
+                        if x:
+                            expr.append(repr(x))
+                self.parsed_attributes[key] = " + ".join(expr) or repr('')
+            elif key in nonexpressions:
+                if re.search(r'\${.+?}', self.attributes[key]):
+                    raise exceptions.CompileException(
+                            "Attibute '%s' in tag '%s' does not allow embedded "
+                            "expressions"  % (key, self.keyword), 
+                            **self.exception_kwargs)
+                self.parsed_attributes[key] = repr(self.attributes[key])
+            else:
+                raise exceptions.CompileException(
+                                    "Invalid attribute for tag '%s': '%s'" %
+                                    (self.keyword, key), 
+                                    **self.exception_kwargs)
+        self.expression_undeclared_identifiers = undeclared_identifiers
+
+    def declared_identifiers(self):
+        return []
+
+    def undeclared_identifiers(self):
+        return self.expression_undeclared_identifiers
+
+    def __repr__(self):
+        return "%s(%r, %s, %r, %r)" % (self.__class__.__name__, 
+                                    self.keyword, 
+                                    util.sorted_dict_repr(self.attributes),
+                                    (self.lineno, self.pos), 
+                                    self.nodes
+                                )
+        
+class IncludeTag(Tag):
+    __keyword__ = 'include'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(IncludeTag, self).__init__(
+                                    keyword, 
+                                    attributes, 
+                                    ('file', 'import', 'args'), 
+                                    (), ('file',), **kwargs)
+        self.page_args = ast.PythonCode(
+                                "__DUMMY(%s)" % attributes.get('args', ''),
+                                 **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return []
+
+    def undeclared_identifiers(self):
+        identifiers = self.page_args.undeclared_identifiers.\
+                            difference(set(["__DUMMY"])).\
+                            difference(self.page_args.declared_identifiers)
+        return identifiers.union(super(IncludeTag, self).
+                                    undeclared_identifiers())
+    
+class NamespaceTag(Tag):
+    __keyword__ = 'namespace'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(NamespaceTag, self).__init__(
+                                        keyword, attributes, 
+                                        ('file',), 
+                                        ('name','inheritable',
+                                        'import','module'), 
+                                        (), **kwargs)
+                                        
+        self.name = attributes.get('name', '__anon_%s' % hex(abs(id(self))))
+        if not 'name' in attributes and not 'import' in attributes:
+            raise exceptions.CompileException(
+                            "'name' and/or 'import' attributes are required "
+                            "for <%namespace>", 
+                                **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return []
+
+class TextTag(Tag):
+    __keyword__ = 'text'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(TextTag, self).__init__(
+                                    keyword, 
+                                    attributes, (), 
+                                    ('filter'), (), **kwargs)
+        self.filter_args = ast.ArgumentList(
+                                    attributes.get('filter', ''), 
+                                    **self.exception_kwargs)
+        
+class DefTag(Tag):
+    __keyword__ = 'def'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(DefTag, self).__init__(
+                keyword, 
+                attributes, 
+                ('buffered', 'cached', 'cache_key', 'cache_timeout', 
+                    'cache_type', 'cache_dir', 'cache_url'), 
+                ('name','filter', 'decorator'), 
+                ('name',), 
+                **kwargs)
+        name = attributes['name']
+        if re.match(r'^[\w_]+$',name):
+            raise exceptions.CompileException(
+                                "Missing parenthesis in %def", 
+                                **self.exception_kwargs)
+        self.function_decl = ast.FunctionDecl("def " + name + ":pass", 
+                                                    **self.exception_kwargs)
+        self.name = self.function_decl.funcname
+        self.decorator = attributes.get('decorator', '')
+        self.filter_args = ast.ArgumentList(
+                                attributes.get('filter', ''), 
+                                **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return self.function_decl.argnames
+
+    def undeclared_identifiers(self):
+        res = []
+        for c in self.function_decl.defaults:
+            res += list(ast.PythonCode(c, **self.exception_kwargs).
+                                    undeclared_identifiers)
+        return res + list(self.filter_args.\
+                            undeclared_identifiers.\
+                            difference(list(filters.DEFAULT_ESCAPES.keys()))
+                        )
+
+class CallTag(Tag):
+    __keyword__ = 'call'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(CallTag, self).__init__(keyword, attributes, 
+                                    ('args'), ('expr',), ('expr',), **kwargs)
+        self.expression = attributes['expr']
+        self.code = ast.PythonCode(self.expression, **self.exception_kwargs)
+        self.body_decl = ast.FunctionArgs(attributes.get('args', ''), 
+                                            **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return self.code.declared_identifiers.union(self.body_decl.argnames)
+
+    def undeclared_identifiers(self):
+        return self.code.undeclared_identifiers.\
+                    difference(self.code.declared_identifiers)
+
+class CallNamespaceTag(Tag):
+
+    def __init__(self, namespace, defname, attributes, **kwargs):
+        super(CallNamespaceTag, self).__init__(
+                    namespace + ":" + defname, 
+                    attributes, 
+                    tuple(attributes.keys()) + ('args', ), 
+                    (), 
+                    (), 
+                    **kwargs)
+                    
+        self.expression = "%s.%s(%s)" % (
+                                namespace, 
+                                defname, 
+                                ",".join(["%s=%s" % (k, v) for k, v in
+                                            self.parsed_attributes.items() 
+                                            if k != 'args'])
+                            )
+        self.code = ast.PythonCode(self.expression, **self.exception_kwargs)
+        self.body_decl = ast.FunctionArgs(
+                                    attributes.get('args', ''), 
+                                    **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return self.code.declared_identifiers.union(self.body_decl.argnames)
+
+    def undeclared_identifiers(self):
+        return self.code.undeclared_identifiers.\
+                    difference(self.code.declared_identifiers)
+
+class InheritTag(Tag):
+    __keyword__ = 'inherit'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(InheritTag, self).__init__(
+                                keyword, attributes, 
+                                ('file',), (), ('file',), **kwargs)
+
+class PageTag(Tag):
+    __keyword__ = 'page'
+
+    def __init__(self, keyword, attributes, **kwargs):
+        super(PageTag, self).__init__(
+                keyword, 
+                attributes, 
+                ('cached', 'cache_key', 'cache_timeout', 
+                'cache_type', 'cache_dir', 'cache_url', 
+                'args', 'expression_filter'), 
+                (), 
+                (), 
+                **kwargs)
+        self.body_decl = ast.FunctionArgs(attributes.get('args', ''), 
+                                            **self.exception_kwargs)
+        self.filter_args = ast.ArgumentList(
+                                attributes.get('expression_filter', ''),
+                                **self.exception_kwargs)
+
+    def declared_identifiers(self):
+        return self.body_decl.argnames
+        
+    
diff --git a/lib3/mako-0.3.6/mako/pygen.py b/lib3/mako-0.3.6/mako/pygen.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/pygen.py
@@ -0,0 +1,285 @@
+# pygen.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""utilities for generating and formatting literal Python code."""
+
+import re, string
+from io import StringIO
+from mako import exceptions
+
+class PythonPrinter(object):
+    def __init__(self, stream):
+        # indentation counter
+        self.indent = 0
+        
+        # a stack storing information about why we incremented 
+        # the indentation counter, to help us determine if we
+        # should decrement it
+        self.indent_detail = []
+        
+        # the string of whitespace multiplied by the indent
+        # counter to produce a line
+        self.indentstring = "    "
+        
+        # the stream we are writing to
+        self.stream = stream
+        
+        # a list of lines that represents a buffered "block" of code,
+        # which can be later printed relative to an indent level 
+        self.line_buffer = []
+        
+        self.in_indent_lines = False
+        
+        self._reset_multi_line_flags()
+
+    def write(self, text):
+        self.stream.write(text)
+        
+    def write_indented_block(self, block):
+        """print a line or lines of python which already contain indentation.
+        
+        The indentation of the total block of lines will be adjusted to that of
+        the current indent level.""" 
+        self.in_indent_lines = False
+        for l in re.split(r'\r?\n', block):
+            self.line_buffer.append(l)
+    
+    def writelines(self, *lines):
+        """print a series of lines of python."""
+        for line in lines:
+            self.writeline(line)
+                
+    def writeline(self, line):
+        """print a line of python, indenting it according to the current
+        indent level.
+        
+        this also adjusts the indentation counter according to the
+        content of the line.
+
+        """
+
+        if not self.in_indent_lines:
+            self._flush_adjusted_lines()
+            self.in_indent_lines = True
+
+        decreased_indent = False
+    
+        if (line is None or 
+            re.match(r"^\s*#",line) or
+            re.match(r"^\s*$", line)
+            ):
+            hastext = False
+        else:
+            hastext = True
+
+        is_comment = line and len(line) and line[0] == '#'
+        
+        # see if this line should decrease the indentation level
+        if (not decreased_indent and 
+            not is_comment and 
+            (not hastext or self._is_unindentor(line))
+            ):
+            
+            if self.indent > 0: 
+                self.indent -=1
+                # if the indent_detail stack is empty, the user
+                # probably put extra closures - the resulting
+                # module wont compile.  
+                if len(self.indent_detail) == 0:  
+                    raise exceptions.SyntaxException(
+                                    "Too many whitespace closures")
+                self.indent_detail.pop()
+        
+        if line is None:
+            return
+                
+        # write the line
+        self.stream.write(self._indent_line(line) + "\n")
+        
+        # see if this line should increase the indentation level.
+        # note that a line can both decrase (before printing) and 
+        # then increase (after printing) the indentation level.
+
+        if re.search(r":[ \t]*(?:#.*)?$", line):
+            # increment indentation count, and also
+            # keep track of what the keyword was that indented us,
+            # if it is a python compound statement keyword
+            # where we might have to look for an "unindent" keyword
+            match = re.match(r"^\s*(if|try|elif|while|for)", line)
+            if match:
+                # its a "compound" keyword, so we will check for "unindentors"
+                indentor = match.group(1)
+                self.indent +=1
+                self.indent_detail.append(indentor)
+            else:
+                indentor = None
+                # its not a "compound" keyword.  but lets also
+                # test for valid Python keywords that might be indenting us,
+                # else assume its a non-indenting line
+                m2 = re.match(r"^\s*(def|class|else|elif|except|finally)", line)
+                if m2:
+                    self.indent += 1
+                    self.indent_detail.append(indentor)
+
+    def close(self):
+        """close this printer, flushing any remaining lines."""
+        self._flush_adjusted_lines()
+    
+    def _is_unindentor(self, line):
+        """return true if the given line is an 'unindentor', 
+        relative to the last 'indent' event received.
+        
+        """
+                
+        # no indentation detail has been pushed on; return False
+        if len(self.indent_detail) == 0: 
+            return False
+
+        indentor = self.indent_detail[-1]
+        
+        # the last indent keyword we grabbed is not a 
+        # compound statement keyword; return False
+        if indentor is None: 
+            return False
+        
+        # if the current line doesnt have one of the "unindentor" keywords,
+        # return False
+        match = re.match(r"^\s*(else|elif|except|finally).*\:", line)
+        if not match: 
+            return False
+        
+        # whitespace matches up, we have a compound indentor,
+        # and this line has an unindentor, this
+        # is probably good enough
+        return True
+        
+        # should we decide that its not good enough, heres
+        # more stuff to check.
+        #keyword = match.group(1)
+        
+        # match the original indent keyword 
+        #for crit in [
+        #   (r'if|elif', r'else|elif'),
+        #   (r'try', r'except|finally|else'),
+        #   (r'while|for', r'else'),
+        #]:
+        #   if re.match(crit[0], indentor) and re.match(crit[1], keyword): 
+        #        return True
+        
+        #return False
+        
+    def _indent_line(self, line, stripspace=''):
+        """indent the given line according to the current indent level.
+        
+        stripspace is a string of space that will be truncated from the
+        start of the line before indenting."""
+
+        return re.sub(r"^%s" % stripspace, self.indentstring
+                      * self.indent, line)
+
+    def _reset_multi_line_flags(self):
+        """reset the flags which would indicate we are in a backslashed
+        or triple-quoted section."""
+
+        self.backslashed, self.triplequoted = False, False
+        
+    def _in_multi_line(self, line):
+        """return true if the given line is part of a multi-line block,
+        via backslash or triple-quote."""
+
+        # we are only looking for explicitly joined lines here, not
+        # implicit ones (i.e. brackets, braces etc.).  this is just to
+        # guard against the possibility of modifying the space inside of
+        # a literal multiline string with unfortunately placed
+        # whitespace
+         
+        current_state = (self.backslashed or self.triplequoted) 
+                        
+        if re.search(r"\\$", line):
+            self.backslashed = True
+        else:
+            self.backslashed = False
+            
+        triples = len(re.findall(r"\"\"\"|\'\'\'", line))
+        if triples == 1 or triples % 2 != 0:
+            self.triplequoted = not self.triplequoted
+            
+        return current_state
+
+    def _flush_adjusted_lines(self):
+        stripspace = None
+        self._reset_multi_line_flags()
+        
+        for entry in self.line_buffer:
+            if self._in_multi_line(entry):
+                self.stream.write(entry + "\n")
+            else:
+                entry = entry.expandtabs()
+                if stripspace is None and re.search(r"^[ \t]*[^# \t]", entry):
+                    stripspace = re.match(r"^([ \t]*)", entry).group(1)
+                self.stream.write(self._indent_line(entry, stripspace) + "\n")
+            
+        self.line_buffer = []
+        self._reset_multi_line_flags()
+
+
+def adjust_whitespace(text):
+    """remove the left-whitespace margin of a block of Python code."""
+    
+    state = [False, False]
+    (backslashed, triplequoted) = (0, 1)
+
+    def in_multi_line(line):
+        start_state = (state[backslashed] or state[triplequoted])
+        
+        if re.search(r"\\$", line):
+            state[backslashed] = True
+        else:
+            state[backslashed] = False
+        
+        def match(reg, t):
+            m = re.match(reg, t)
+            if m:
+                return m, t[len(m.group(0)):]
+            else:
+                return None, t
+                
+        while line:
+            if state[triplequoted]:
+                m, line = match(r"%s" % state[triplequoted], line)
+                if m:
+                    state[triplequoted] = False
+                else:
+                    m, line = match(r".*?(?=%s|$)" % state[triplequoted], line)
+            else:
+                m, line = match(r'#', line)
+                if m:
+                    return start_state
+                
+                m, line = match(r"\"\"\"|\'\'\'", line)
+                if m:
+                    state[triplequoted] = m.group(0)
+                    continue
+
+                m, line = match(r".*?(?=\"\"\"|\'\'\'|#|$)", line)
+            
+        return start_state
+
+    def _indent_line(line, stripspace = ''):
+        return re.sub(r"^%s" % stripspace, '', line)
+
+    lines = []
+    stripspace = None
+
+    for line in re.split(r'\r?\n', text):
+        if in_multi_line(line):
+            lines.append(line)
+        else:
+            line = line.expandtabs()
+            if stripspace is None and re.search(r"^[ \t]*[^# \t]", line):
+                stripspace = re.match(r"^([ \t]*)", line).group(1)
+            lines.append(_indent_line(line, stripspace))
+    return "\n".join(lines)
diff --git a/lib3/mako-0.3.6/mako/pyparser.py b/lib3/mako-0.3.6/mako/pyparser.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/pyparser.py
@@ -0,0 +1,533 @@
+# ast.py
+# Copyright (C) Mako developers
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""Handles parsing of Python code.
+
+Parsing to AST is done via _ast on Python > 2.5, otherwise the compiler
+module is used.
+"""
+
+from io import StringIO
+from mako import exceptions, util
+import operator
+
+if util.py3k:
+    # words that cannot be assigned to (notably 
+    # smaller than the total keys in __builtins__)
+    reserved = set(['True', 'False', 'None', 'print'])
+
+    # the "id" attribute on a function node
+    arg_id = operator.attrgetter('arg')
+else:
+    # words that cannot be assigned to (notably 
+    # smaller than the total keys in __builtins__)
+    reserved = set(['True', 'False', 'None'])
+    
+    # the "id" attribute on a function node
+    arg_id = operator.attrgetter('id')
+
+
+try:
+    import _ast
+    util.restore__ast(_ast)
+    from . import _ast_util
+except ImportError:
+    _ast = None
+    from compiler import parse as compiler_parse
+    from compiler import visitor
+
+
+def parse(code, mode='exec', **exception_kwargs):
+    """Parse an expression into AST"""
+    
+
+    try:
+        if _ast:
+            return _ast_util.parse(code, '<unknown>', mode)
+        else:
+            if isinstance(code, str):
+                code = code.encode('ascii', 'backslashreplace')
+            return compiler_parse(code, mode)
+    except Exception as e:
+        raise exceptions.SyntaxException(
+                    "(%s) %s (%r)" % (
+                        e.__class__.__name__, 
+                        e, 
+                        code[0:50]
+                    ), **exception_kwargs)
+
+
+if _ast:
+    class FindIdentifiers(_ast_util.NodeVisitor):
+
+        def __init__(self, listener, **exception_kwargs):
+            self.in_function = False
+            self.in_assign_targets = False
+            self.local_ident_stack = {}
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+
+        def _add_declared(self, name):
+            if not self.in_function:
+                self.listener.declared_identifiers.add(name)
+
+        def visit_ClassDef(self, node):
+            self._add_declared(node.name)
+
+        def visit_Assign(self, node):
+
+            # flip around the visiting of Assign so the expression gets
+            # evaluated first, in the case of a clause like "x=x+5" (x
+            # is undeclared)
+
+            self.visit(node.value)
+            in_a = self.in_assign_targets
+            self.in_assign_targets = True
+            for n in node.targets:
+                self.visit(n)
+            self.in_assign_targets = in_a
+
+        if util.py3k:
+
+            # ExceptHandler is in Python 2, but this block only works in
+            # Python 3 (and is required there)
+
+            def visit_ExceptHandler(self, node):
+                if node.name is not None:
+                    self._add_declared(node.name)
+                if node.type is not None:
+                    self.listener.undeclared_identifiers.add(node.type.id)
+                for statement in node.body:
+                    self.visit(statement)
+
+        def visit_Lambda(self, node, *args):
+            self._visit_function(node, True)
+
+        def visit_FunctionDef(self, node):
+            self._add_declared(node.name)
+            self._visit_function(node, False)
+
+        def _visit_function(self, node, islambda):
+
+            # push function state onto stack.  dont log any more
+            # identifiers as "declared" until outside of the function,
+            # but keep logging identifiers as "undeclared". track
+            # argument names in each function header so they arent
+            # counted as "undeclared"
+
+            saved = {}
+            inf = self.in_function
+            self.in_function = True
+            for arg in node.args.args:
+                if arg_id(arg) in self.local_ident_stack:
+                    saved[arg_id(arg)] = True
+                else:
+                    self.local_ident_stack[arg_id(arg)] = True
+            if islambda:
+                self.visit(node.body)
+            else:
+                for n in node.body:
+                    self.visit(n)
+            self.in_function = inf
+            for arg in node.args.args:
+                if arg_id(arg) not in saved:
+                    del self.local_ident_stack[arg_id(arg)]
+
+        def visit_For(self, node):
+
+            # flip around visit
+
+            self.visit(node.iter)
+            self.visit(node.target)
+            for statement in node.body:
+                self.visit(statement)
+            for statement in node.orelse:
+                self.visit(statement)
+
+        def visit_Name(self, node):
+            if isinstance(node.ctx, _ast.Store):
+                self._add_declared(node.id)
+            if node.id not in reserved and node.id \
+                not in self.listener.declared_identifiers and node.id \
+                not in self.local_ident_stack:
+                self.listener.undeclared_identifiers.add(node.id)
+
+        def visit_Import(self, node):
+            for name in node.names:
+                if name.asname is not None:
+                    self._add_declared(name.asname)
+                else:
+                    self._add_declared(name.name.split('.')[0])
+
+        def visit_ImportFrom(self, node):
+            for name in node.names:
+                if name.asname is not None:
+                    self._add_declared(name.asname)
+                else:
+                    if name.name == '*':
+                        raise exceptions.CompileException(
+                          "'import *' is not supported, since all identifier "
+                          "names must be explicitly declared.  Please use the "
+                          "form 'from <modulename> import <name1>, <name2>, "
+                          "...' instead.", **self.exception_kwargs)
+                    self._add_declared(name.name)
+
+
+    class FindTuple(_ast_util.NodeVisitor):
+
+        def __init__(self, listener, code_factory, **exception_kwargs):
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+            self.code_factory = code_factory
+
+        def visit_Tuple(self, node):
+            for n in node.elts:
+                p = self.code_factory(n, **self.exception_kwargs)
+                self.listener.codeargs.append(p)
+                self.listener.args.append(ExpressionGenerator(n).value())
+                self.listener.declared_identifiers = \
+                    self.listener.declared_identifiers.union(
+                                                    p.declared_identifiers)
+                self.listener.undeclared_identifiers = \
+                    self.listener.undeclared_identifiers.union(
+                                                    p.undeclared_identifiers)
+
+
+    class ParseFunc(_ast_util.NodeVisitor):
+
+        def __init__(self, listener, **exception_kwargs):
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+
+        def visit_FunctionDef(self, node):
+            self.listener.funcname = node.name
+            argnames = [arg_id(arg) for arg in node.args.args]
+            if node.args.vararg:
+                argnames.append(node.args.vararg)
+            if node.args.kwarg:
+                argnames.append(node.args.kwarg)
+            self.listener.argnames = argnames
+            self.listener.defaults = node.args.defaults  # ast
+            self.listener.varargs = node.args.vararg
+            self.listener.kwargs = node.args.kwarg
+
+
+    class ExpressionGenerator(object):
+
+        def __init__(self, astnode):
+            self.generator = _ast_util.SourceGenerator(' ' * 4)
+            self.generator.visit(astnode)
+
+        def value(self):
+            return ''.join(self.generator.result)
+else:
+    class FindIdentifiers(object):
+
+        def __init__(self, listener, **exception_kwargs):
+            self.in_function = False
+            self.local_ident_stack = {}
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+
+        def _add_declared(self, name):
+            if not self.in_function:
+                self.listener.declared_identifiers.add(name)
+
+        def visitClass(self, node, *args):
+            self._add_declared(node.name)
+
+        def visitAssName(self, node, *args):
+            self._add_declared(node.name)
+
+        def visitAssign(self, node, *args):
+
+            # flip around the visiting of Assign so the expression gets
+            # evaluated first, in the case of a clause like "x=x+5" (x
+            # is undeclared)
+
+            self.visit(node.expr, *args)
+            for n in node.nodes:
+                self.visit(n, *args)
+
+        def visitLambda(self, node, *args):
+            self._visit_function(node, args)
+
+        def visitFunction(self, node, *args):
+            self._add_declared(node.name)
+            self._visit_function(node, args)
+
+        def _visit_function(self, node, args):
+
+            # push function state onto stack.  dont log any more
+            # identifiers as "declared" until outside of the function,
+            # but keep logging identifiers as "undeclared". track
+            # argument names in each function header so they arent
+            # counted as "undeclared"
+
+            saved = {}
+            inf = self.in_function
+            self.in_function = True
+            for arg in node.argnames:
+                if arg in self.local_ident_stack:
+                    saved[arg] = True
+                else:
+                    self.local_ident_stack[arg] = True
+            for n in node.getChildNodes():
+                self.visit(n, *args)
+            self.in_function = inf
+            for arg in node.argnames:
+                if arg not in saved:
+                    del self.local_ident_stack[arg]
+
+        def visitFor(self, node, *args):
+
+            # flip around visit
+
+            self.visit(node.list, *args)
+            self.visit(node.assign, *args)
+            self.visit(node.body, *args)
+
+        def visitName(self, node, *args):
+            if node.name not in reserved and node.name \
+                not in self.listener.declared_identifiers and node.name \
+                not in self.local_ident_stack:
+                self.listener.undeclared_identifiers.add(node.name)
+
+        def visitImport(self, node, *args):
+            for mod, alias in node.names:
+                if alias is not None:
+                    self._add_declared(alias)
+                else:
+                    self._add_declared(mod.split('.')[0])
+
+        def visitFrom(self, node, *args):
+            for mod, alias in node.names:
+                if alias is not None:
+                    self._add_declared(alias)
+                else:
+                    if mod == '*':
+                        raise exceptions.CompileException(
+                        "'import *' is not supported, since all identifier "
+                        "names must be explicitly declared.  Please use the "
+                        "form 'from <modulename> import <name1>, <name2>, "
+                        "...' instead.", **self.exception_kwargs)
+                    self._add_declared(mod)
+
+        def visit(self, expr):
+            visitor.walk(expr, self)  # , walker=walker())
+
+
+    class FindTuple(object):
+
+        def __init__(self, listener, code_factory, **exception_kwargs):
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+            self.code_factory = code_factory
+
+        def visitTuple(self, node, *args):
+            for n in node.nodes:
+                p = self.code_factory(n, **self.exception_kwargs)
+                self.listener.codeargs.append(p)
+                self.listener.args.append(ExpressionGenerator(n).value())
+                self.listener.declared_identifiers = \
+                    self.listener.declared_identifiers.union(p.declared_identifiers)
+                self.listener.undeclared_identifiers = \
+                    self.listener.undeclared_identifiers.union(p.undeclared_identifiers)
+
+        def visit(self, expr):
+            visitor.walk(expr, self)  # , walker=walker())
+
+
+    class ParseFunc(object):
+
+        def __init__(self, listener, **exception_kwargs):
+            self.listener = listener
+            self.exception_kwargs = exception_kwargs
+
+        def visitFunction(self, node, *args):
+            self.listener.funcname = node.name
+            self.listener.argnames = node.argnames
+            self.listener.defaults = node.defaults
+            self.listener.varargs = node.varargs
+            self.listener.kwargs = node.kwargs
+
+        def visit(self, expr):
+            visitor.walk(expr, self)
+
+
+    class ExpressionGenerator(object):
+
+        """given an AST node, generates an equivalent literal Python
+        expression."""
+
+        def __init__(self, astnode):
+            self.buf = StringIO()
+            visitor.walk(astnode, self)  # , walker=walker())
+
+        def value(self):
+            return self.buf.getvalue()
+
+        def operator(self, op, node, *args):
+            self.buf.write('(')
+            self.visit(node.left, *args)
+            self.buf.write(' %s ' % op)
+            self.visit(node.right, *args)
+            self.buf.write(')')
+
+        def booleanop(self, op, node, *args):
+            self.visit(node.nodes[0])
+            for n in node.nodes[1:]:
+                self.buf.write(' ' + op + ' ')
+                self.visit(n, *args)
+
+        def visitConst(self, node, *args):
+            self.buf.write(repr(node.value))
+
+        def visitAssName(self, node, *args):
+
+            # TODO: figure out OP_ASSIGN, other OP_s
+
+            self.buf.write(node.name)
+
+        def visitName(self, node, *args):
+            self.buf.write(node.name)
+
+        def visitMul(self, node, *args):
+            self.operator('*', node, *args)
+
+        def visitAnd(self, node, *args):
+            self.booleanop('and', node, *args)
+
+        def visitOr(self, node, *args):
+            self.booleanop('or', node, *args)
+
+        def visitBitand(self, node, *args):
+            self.booleanop('&', node, *args)
+
+        def visitBitor(self, node, *args):
+            self.booleanop('|', node, *args)
+
+        def visitBitxor(self, node, *args):
+            self.booleanop('^', node, *args)
+
+        def visitAdd(self, node, *args):
+            self.operator('+', node, *args)
+
+        def visitGetattr(self, node, *args):
+            self.visit(node.expr, *args)
+            self.buf.write('.%s' % node.attrname)
+
+        def visitSub(self, node, *args):
+            self.operator('-', node, *args)
+
+        def visitNot(self, node, *args):
+            self.buf.write('not ')
+            self.visit(node.expr)
+
+        def visitDiv(self, node, *args):
+            self.operator('/', node, *args)
+
+        def visitFloorDiv(self, node, *args):
+            self.operator('//', node, *args)
+
+        def visitSubscript(self, node, *args):
+            self.visit(node.expr)
+            self.buf.write('[')
+            [self.visit(x) for x in node.subs]
+            self.buf.write(']')
+
+        def visitUnarySub(self, node, *args):
+            self.buf.write('-')
+            self.visit(node.expr)
+
+        def visitUnaryAdd(self, node, *args):
+            self.buf.write('-')
+            self.visit(node.expr)
+
+        def visitSlice(self, node, *args):
+            self.visit(node.expr)
+            self.buf.write('[')
+            if node.lower is not None:
+                self.visit(node.lower)
+            self.buf.write(':')
+            if node.upper is not None:
+                self.visit(node.upper)
+            self.buf.write(']')
+
+        def visitDict(self, node):
+            self.buf.write('{')
+            c = node.getChildren()
+            for i in range(0, len(c), 2):
+                self.visit(c[i])
+                self.buf.write(': ')
+                self.visit(c[i + 1])
+                if i < len(c) - 2:
+                    self.buf.write(', ')
+            self.buf.write('}')
+
+        def visitTuple(self, node):
+            self.buf.write('(')
+            c = node.getChildren()
+            for i in range(0, len(c)):
+                self.visit(c[i])
+                if i < len(c) - 1:
+                    self.buf.write(', ')
+            self.buf.write(')')
+
+        def visitList(self, node):
+            self.buf.write('[')
+            c = node.getChildren()
+            for i in range(0, len(c)):
+                self.visit(c[i])
+                if i < len(c) - 1:
+                    self.buf.write(', ')
+            self.buf.write(']')
+
+        def visitListComp(self, node):
+            self.buf.write('[')
+            self.visit(node.expr)
+            self.buf.write(' ')
+            for n in node.quals:
+                self.visit(n)
+            self.buf.write(']')
+
+        def visitListCompFor(self, node):
+            self.buf.write(' for ')
+            self.visit(node.assign)
+            self.buf.write(' in ')
+            self.visit(node.list)
+            for n in node.ifs:
+                self.visit(n)
+
+        def visitListCompIf(self, node):
+            self.buf.write(' if ')
+            self.visit(node.test)
+
+        def visitCompare(self, node):
+            self.visit(node.expr)
+            for tup in node.ops:
+                self.buf.write(tup[0])
+                self.visit(tup[1])
+
+        def visitCallFunc(self, node, *args):
+            self.visit(node.node)
+            self.buf.write('(')
+            if len(node.args):
+                self.visit(node.args[0])
+                for a in node.args[1:]:
+                    self.buf.write(', ')
+                    self.visit(a)
+            self.buf.write(')')
+
+
+    class walker(visitor.ASTVisitor):
+
+        def dispatch(self, node, *args):
+            print('Node:', str(node))
+
+            # print "dir:", dir(node)
+
+            return visitor.ASTVisitor.dispatch(self, node, *args)
diff --git a/lib3/mako-0.3.6/mako/runtime.py b/lib3/mako-0.3.6/mako/runtime.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/runtime.py
@@ -0,0 +1,651 @@
+# runtime.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""provides runtime services for templates, including Context,
+Namespace, and various helper functions."""
+
+from mako import exceptions, util
+import builtins, inspect, sys
+import collections
+
+class Context(object):
+    """Provides runtime namespace, output buffer, and various
+    callstacks for templates.
+    
+     See :ref:`runtime_toplevel` for detail on the usage of
+    :class:`.Context`.
+    
+     """
+    
+    def __init__(self, buffer, **data):
+        self._buffer_stack = [buffer]
+        
+        # original data, minus the builtins
+        self._orig = data
+        
+        # the context data which includes builtins
+        self._data = builtins.__dict__.copy()
+        self._data.update(data)
+        self._kwargs = data.copy()
+        self._with_template = None
+        self._outputting_as_unicode = None
+        self.namespaces = {}
+        
+        # "capture" function which proxies to the 
+        # generic "capture" function
+        self._data['capture'] = util.partial(capture, self)
+        
+        # "caller" stack used by def calls with content
+        self.caller_stack = self._data['caller'] = CallerStack()
+        
+    @property
+    def lookup(self):
+        """Return the :class:`.TemplateLookup` associated 
+        with this :class:`.Context`.
+        
+        """
+        return self._with_template.lookup
+        
+    @property
+    def kwargs(self):
+        """Return the dictionary of keyword argments associated with this
+        :class:`.Context`.
+        
+        """
+        return self._kwargs.copy()
+    
+    def push_caller(self, caller):
+        """Pushes a 'caller' callable onto the callstack for
+        this :class:`.Context`."""
+        
+        
+        self.caller_stack.append(caller)
+        
+    def pop_caller(self):
+        """Pops a 'caller' callable onto the callstack for this
+        :class:`.Context`."""
+
+        del self.caller_stack[-1]
+        
+    def keys(self):
+        """Return a list of all names established in this :class:`.Context`."""
+
+        return list(self._data.keys())
+        
+    def __getitem__(self, key):
+        return self._data[key]
+
+    def _push_writer(self):
+        """push a capturing buffer onto this Context and return
+        the new writer function."""
+        
+        buf = util.FastEncodingBuffer()
+        self._buffer_stack.append(buf)
+        return buf.write
+
+    def _pop_buffer_and_writer(self):
+        """pop the most recent capturing buffer from this Context 
+        and return the current writer after the pop.
+        
+        """
+
+        buf = self._buffer_stack.pop()
+        return buf, self._buffer_stack[-1].write
+        
+    def _push_buffer(self):
+        """push a capturing buffer onto this Context."""
+        
+        self._push_writer()
+        
+    def _pop_buffer(self):
+        """pop the most recent capturing buffer from this Context."""
+        
+        return self._buffer_stack.pop()
+        
+    def get(self, key, default=None):
+        """Return a value from this :class:`.Context`."""
+        
+        return self._data.get(key, default)
+        
+    def write(self, string):
+        """Write a string to this :class:`.Context` object's
+        underlying output buffer."""
+        
+        self._buffer_stack[-1].write(string)
+        
+    def writer(self):
+        """Return the current writer function"""
+
+        return self._buffer_stack[-1].write
+
+    def _copy(self):
+        c = Context.__new__(Context)
+        c._buffer_stack = self._buffer_stack
+        c._data = self._data.copy()
+        c._orig = self._orig
+        c._kwargs = self._kwargs
+        c._with_template = self._with_template
+        c._outputting_as_unicode = self._outputting_as_unicode
+        c.namespaces = self.namespaces
+        c.caller_stack = self.caller_stack
+        return c
+        
+    def locals_(self, d):
+        """create a new :class:`.Context` with a copy of this 
+        :class:`Context`'s current state, updated with the given dictionary."""
+        
+        if len(d) == 0:
+            return self
+        c = self._copy()
+        c._data.update(d)
+        return c
+        
+    def _clean_inheritance_tokens(self):
+        """create a new copy of this :class:`.Context`. with
+        tokens related to inheritance state removed."""
+
+        c = self._copy()
+        x = c._data
+        x.pop('self', None)
+        x.pop('parent', None)
+        x.pop('next', None)
+        return c
+
+class CallerStack(list):
+    def __init__(self):
+        self.nextcaller = None
+    def __bool__(self):
+        return self._get_caller() and True or False
+    def _get_caller(self):
+        return self[-1]
+    def __getattr__(self, key):
+        return getattr(self._get_caller(), key)
+    def _push_frame(self):
+        self.append(self.nextcaller or None)
+        self.nextcaller = None
+    def _pop_frame(self):
+        self.nextcaller = self.pop()
+        
+        
+class Undefined(object):
+    """Represents an undefined value in a template.
+    
+    All template modules have a constant value 
+    ``UNDEFINED`` present which is an instance of this
+    object.
+    
+    """
+    def __str__(self):
+        raise NameError("Undefined")
+    def __bool__(self):
+        return False
+
+UNDEFINED = Undefined()
+
+class _NSAttr(object):
+    def __init__(self, parent):
+        self.__parent = parent
+    def __getattr__(self, key):
+        ns = self.__parent
+        while ns:
+            if hasattr(ns.module, key):
+                return getattr(ns.module, key)
+            else:
+                ns = ns.inherits
+        raise AttributeError(key)    
+    
+class Namespace(object):
+    """Provides access to collections of rendering methods, which 
+      can be local, from other templates, or from imported modules.
+      
+      To access a particular rendering method referenced by a 
+      :class:`.Namespace`, use plain attribute access::
+      
+        ${some_namespace.foo(x, y, z)}
+        
+      :class:`.Namespace` also contains several built-in attributes 
+      described here.
+      
+      """
+    
+    def __init__(self, name, context, module=None, 
+                            template=None, templateuri=None, 
+                            callables=None, inherits=None, 
+                            populate_self=True, calling_uri=None):
+        self.name = name
+        if module is not None:
+            mod = __import__(module)
+            for token in module.split('.')[1:]:
+                mod = getattr(mod, token)
+            self._module = mod
+        else:
+            self._module = None
+        if templateuri is not None:
+            self.template = _lookup_template(context, templateuri, calling_uri)
+            self._templateuri = self.template.module._template_uri
+        else:
+            self.template = template
+            if self.template is not None:
+                self._templateuri = self.template.module._template_uri
+        self.context = context
+        self.inherits = inherits
+        if callables is not None:
+            self.callables = dict([(c.__name__, c) for c in callables])
+        else:
+            self.callables = None
+        if populate_self and self.template is not None:
+            lclcallable, lclcontext = \
+                        _populate_self_namespace(context, self.template, self_ns=self)
+    
+    template = None
+    """The :class:`.Template` object referenced by this
+        :class:`.Namespace`, if any.
+
+    """
+
+    context = None
+    """The :class:`.Context` object for this namespace.
+    
+    Namespaces are often created with copies of contexts that
+    contain slightly different data, particularly in inheritance
+    scenarios. Using the :class:`.Context` off of a :class:`.Namespace` one
+    can traverse an entire chain of templates that inherit from
+    one-another.
+
+    """
+    
+    
+    @property
+    def module(self):
+        """The Python module referenced by this Namespace.
+        
+        If the namespace references a :class:`.Template`, then
+        this module is the equivalent of ``template.module``,
+        i.e. the generated module for the template.
+
+        """
+        return self._module or self.template.module
+    
+    @property
+    def filename(self):
+        """The path of the filesystem file used for this
+        Namespace's module or template.
+      
+        If this is a pure module-based
+        Namespace, this evaluates to ``module.__file__``. If a
+        template-based namespace, it evaluates to the original
+        template file location.
+        
+        """
+        if self._module:
+            return self._module.__file__
+        else:
+            return self.template.filename
+    
+    @property
+    def uri(self):
+        """The uri for this Namespace's template.
+        
+        I.e. whatever was sent to :meth:`.TemplateLookup.get_template()`.
+        
+        This is the equivalent of :attr:`Template.uri`.
+
+        """
+        return self.template.uri
+
+    @property
+    def attr(self):
+        """Access module level attributes by name. 
+        
+        This accessor allows templates to supply "scalar"
+        attributes which are particularly handy in inheritance
+        relationships. See the example in
+        :ref:`inheritance_toplevel`.
+
+        """
+        if not hasattr(self, '_attr'):
+            self._attr = _NSAttr(self)
+        return self._attr
+
+    def get_namespace(self, uri):
+        """Return a :class:`.Namespace` corresponding to the given uri.
+        
+        If the given uri is a relative uri (i.e. it does not
+        contain ia leading slash ``/``), the uri is adjusted to
+        be relative to the uri of the namespace itself. This
+        method is therefore mostly useful off of the built-in
+        ``local`` namespace, described in :ref:`namespace_local`
+
+        In
+        most cases, a template wouldn't need this function, and
+        should instead use the ``<%namespace>`` tag to load
+        namespaces. However, since all ``<%namespace>`` tags are
+        evaulated before the body of a template ever runs,
+        this method can be used to locate namespaces using
+        expressions that were generated within the body code of
+        the template, or to conditionally use a particular
+        namespace.
+        
+        """
+        key = (self, uri)
+        if key in self.context.namespaces:
+            return self.context.namespaces[key]
+        else:
+            ns = Namespace(uri, self.context._copy(), 
+                                templateuri=uri, 
+                                calling_uri=self._templateuri) 
+            self.context.namespaces[key] = ns
+            return ns
+    
+    def get_template(self, uri):
+        """Return a :class:`.Template` from the given uri.
+        
+        The uri resolution is relative to the uri of this :class:`.Namespace`
+        object's :class:`.Template`.
+        
+        """
+        return _lookup_template(self.context, uri, self._templateuri)
+        
+    def get_cached(self, key, **kwargs):
+        """Return a value from the :class:`.Cache` referenced by this 
+        :class:`.Namespace` object's :class:`.Template`.
+        
+        The advantage to this method versus direct access to the 
+        :class:`.Cache` is that the configuration parameters
+        declared in ``<%page>`` take effect here, thereby calling
+        up the same configured backend as that configured
+        by ``<%page>``.
+        
+        """
+        
+        if self.template:
+            if not self.template.cache_enabled:
+                createfunc = kwargs.get('createfunc', None)
+                if createfunc:
+                    return createfunc()
+                else:
+                    return None
+                
+            if self.template.cache_dir:
+                kwargs.setdefault('data_dir', self.template.cache_dir)
+            if self.template.cache_type:
+                kwargs.setdefault('type', self.template.cache_type)
+            if self.template.cache_url:
+                kwargs.setdefault('url', self.template.cache_url)
+        return self.cache.get(key, **kwargs)
+    
+    @property
+    def cache(self):
+        """Return the :class:`.Cache` object referenced by this :class:`.Namespace` object's
+        :class:`.Template`.
+        
+        """
+        return self.template.cache
+    
+    def include_file(self, uri, **kwargs):
+        """Include a file at the given uri"""
+        
+        _include_file(self.context, uri, self._templateuri, **kwargs)
+        
+    def _populate(self, d, l):
+        for ident in l:
+            if ident == '*':
+                for (k, v) in self._get_star():
+                    d[k] = v
+            else:
+                d[ident] = getattr(self, ident)
+    
+    def _get_star(self):
+        if self.callables:
+            for key in self.callables:
+                yield (key, self.callables[key])
+        if self.template:
+            def get(key):
+                callable_ = self.template._get_def_callable(key)
+                return util.partial(callable_, self.context)
+            for k in self.template.module._exports:
+                yield (k, get(k))
+        if self._module:
+            def get(key):
+                callable_ = getattr(self._module, key)
+                return util.partial(callable_, self.context)
+            for k in dir(self._module):
+                if k[0] != '_':
+                    yield (k, get(k))
+                            
+    def __getattr__(self, key):
+        if self.callables and key in self.callables:
+            return self.callables[key]
+
+        if self.template and self.template.has_def(key):
+            callable_ = self.template._get_def_callable(key)
+            return util.partial(callable_, self.context)
+
+        if self._module and hasattr(self._module, key):
+            callable_ = getattr(self._module, key)
+            return util.partial(callable_, self.context)
+
+        if self.inherits is not None:
+            return getattr(self.inherits, key)
+        raise AttributeError(
+                    "Namespace '%s' has no member '%s'" % 
+                    (self.name, key))
+
+def supports_caller(func):
+    """Apply a caller_stack compatibility decorator to a plain
+    Python function.
+    
+    See the example in :ref:`namespaces_python_modules`.
+    
+    """
+    
+    def wrap_stackframe(context,  *args, **kwargs):
+        context.caller_stack._push_frame()
+        try:
+            return func(context, *args, **kwargs)
+        finally:
+            context.caller_stack._pop_frame()
+    return wrap_stackframe
+        
+def capture(context, callable_, *args, **kwargs):
+    """Execute the given template def, capturing the output into
+    a buffer.
+    
+    See the example in :ref:`namespaces_python_modules`.
+    
+    """
+    
+    if not isinstance(callable_, collections.Callable):
+        raise exceptions.RuntimeException(
+                            "capture() function expects a callable as "
+                            "its argument (i.e. capture(func, *args, **kwargs))"
+                        )
+    context._push_buffer()
+    try:
+        callable_(*args, **kwargs)
+    finally:
+        buf = context._pop_buffer()
+    return buf.getvalue()
+
+def _decorate_toplevel(fn):
+    def decorate_render(render_fn):
+        def go(context, *args, **kw):
+            def y(*args, **kw):
+                return render_fn(context, *args, **kw)
+            try:
+                y.__name__ = render_fn.__name__[7:]
+            except TypeError:
+                # < Python 2.4
+                pass
+            return fn(y)(context, *args, **kw)
+        return go
+    return decorate_render
+    
+def _decorate_inline(context, fn):
+    def decorate_render(render_fn):
+        dec = fn(render_fn)
+        def go(*args, **kw):
+            return dec(context, *args, **kw)
+        return go
+    return decorate_render
+            
+def _include_file(context, uri, calling_uri, **kwargs):
+    """locate the template from the given uri and include it in
+    the current output."""
+    
+    template = _lookup_template(context, uri, calling_uri)
+    (callable_, ctx) = _populate_self_namespace(
+                                context._clean_inheritance_tokens(), 
+                                template)
+    callable_(ctx, **_kwargs_for_include(callable_, context._orig, **kwargs))
+        
+def _inherit_from(context, uri, calling_uri):
+    """called by the _inherit method in template modules to set
+    up the inheritance chain at the start of a template's
+    execution."""
+
+    if uri is None:
+        return None
+    template = _lookup_template(context, uri, calling_uri)
+    self_ns = context['self']
+    ih = self_ns
+    while ih.inherits is not None:
+        ih = ih.inherits
+    lclcontext = context.locals_({'next':ih})
+    ih.inherits = Namespace("self:%s" % template.uri, 
+                                lclcontext, 
+                                template = template, 
+                                populate_self=False)
+    context._data['parent'] = lclcontext._data['local'] = ih.inherits
+    callable_ = getattr(template.module, '_mako_inherit', None)
+    if callable_ is not None:
+        ret = callable_(template, lclcontext)
+        if ret:
+            return ret
+
+    gen_ns = getattr(template.module, '_mako_generate_namespaces', None)
+    if gen_ns is not None:
+        gen_ns(context)
+    return (template.callable_, lclcontext)
+
+def _lookup_template(context, uri, relativeto):
+    lookup = context._with_template.lookup
+    if lookup is None:
+        raise exceptions.TemplateLookupException(
+                            "Template '%s' has no TemplateLookup associated" % 
+                            context._with_template.uri)
+    uri = lookup.adjust_uri(uri, relativeto)
+    try:
+        return lookup.get_template(uri)
+    except exceptions.TopLevelLookupException as e:
+        raise exceptions.TemplateLookupException(str(e))
+
+def _populate_self_namespace(context, template, self_ns=None):
+    if self_ns is None:
+        self_ns = Namespace('self:%s' % template.uri, 
+                                context, template=template, 
+                                populate_self=False)
+    context._data['self'] = context._data['local'] = self_ns
+    if hasattr(template.module, '_mako_inherit'):
+        ret = template.module._mako_inherit(template, context)
+        if ret:
+            return ret
+    return (template.callable_, context)
+
+def _render(template, callable_, args, data, as_unicode=False):
+    """create a Context and return the string 
+    output of the given template and template callable."""
+
+    if as_unicode:
+        buf = util.FastEncodingBuffer(str=True)
+    elif template.output_encoding:
+        buf = util.FastEncodingBuffer(
+                        str=as_unicode, 
+                        encoding=template.output_encoding, 
+                        errors=template.encoding_errors)
+    else:
+        buf = util.StringIO()
+    context = Context(buf, **data)
+    context._outputting_as_unicode = as_unicode
+    context._with_template = template
+    
+    _render_context(template, callable_, context, *args, 
+                            **_kwargs_for_callable(callable_, data))
+    return context._pop_buffer().getvalue()
+
+def _kwargs_for_callable(callable_, data):
+    argspec = inspect.getargspec(callable_)
+    # for normal pages, **pageargs is usually present
+    if argspec[2]:
+        return data
+    
+    # for rendering defs from the top level, figure out the args
+    namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
+    kwargs = {}
+    for arg in namedargs:
+        if arg != 'context' and arg in data and arg not in kwargs:
+            kwargs[arg] = data[arg]
+    return kwargs
+
+def _kwargs_for_include(callable_, data, **kwargs):
+    argspec = inspect.getargspec(callable_)
+    namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
+    for arg in namedargs:
+        if arg != 'context' and arg in data and arg not in kwargs:
+            kwargs[arg] = data[arg]
+    return kwargs
+    
+def _render_context(tmpl, callable_, context, *args, **kwargs):
+    import mako.template as template
+    # create polymorphic 'self' namespace for this 
+    # template with possibly updated context
+    if not isinstance(tmpl, template.DefTemplate):
+        # if main render method, call from the base of the inheritance stack
+        (inherit, lclcontext) = _populate_self_namespace(context, tmpl)
+        _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
+    else:
+        # otherwise, call the actual rendering method specified
+        (inherit, lclcontext) = _populate_self_namespace(context, tmpl.parent)
+        _exec_template(callable_, context, args=args, kwargs=kwargs)
+        
+def _exec_template(callable_, context, args=None, kwargs=None):
+    """execute a rendering callable given the callable, a
+    Context, and optional explicit arguments
+
+    the contextual Template will be located if it exists, and
+    the error handling options specified on that Template will
+    be interpreted here.
+    """
+    template = context._with_template
+    if template is not None and \
+            (template.format_exceptions or template.error_handler):
+        error = None
+        try:
+            callable_(context, *args, **kwargs)
+        except Exception as e:
+            _render_error(template, context, e)
+        except:                
+            e = sys.exc_info()[0]
+            _render_error(template, context, e)
+    else:
+        callable_(context, *args, **kwargs)
+
+def _render_error(template, context, error):
+    if template.error_handler:
+        result = template.error_handler(context, error)
+        if not result:
+            raise error
+    else:
+        error_template = exceptions.html_error_template()
+        if context._outputting_as_unicode:
+            context._buffer_stack[:] = [util.FastEncodingBuffer(str=True)]
+        else:
+            context._buffer_stack[:] = [util.FastEncodingBuffer(
+                                            error_template.output_encoding,
+                                            error_template.encoding_errors)]
+                                            
+        context._with_template = error_template
+        error_template.render_context(context, error=error)
diff --git a/lib3/mako-0.3.6/mako/template.py b/lib3/mako-0.3.6/mako/template.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/template.py
@@ -0,0 +1,510 @@
+# template.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer
+# mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""Provides the Template class, a facade for parsing, generating and executing
+template strings, as well as template runtime operations."""
+
+from mako.lexer import Lexer
+from mako import runtime, util, exceptions, codegen
+import imp, os, re, shutil, stat, sys, tempfile, time, types, weakref
+
+    
+class Template(object):
+    """Represents a compiled template.
+    
+    :class:`.Template` includes a reference to the original
+    template source (via the ``.source`` attribute) 
+    as well as the source code of the
+    generated Python module (i.e. the ``.code`` attribute), 
+    as well as a reference to an actual Python module.
+
+    :class:`.Template` is constructed using either a literal string
+    representing the template text, or a filename representing a filesystem
+    path to a source file.
+    
+    :param text: textual template source.  This argument is mutually
+     exclusive versus the "filename" parameter.
+
+    :param filename: filename of the source template.  This argument is 
+     mutually exclusive versus the "text" parameter.
+
+    :param buffer_filters: string list of filters to be applied
+     to the output of %defs which are buffered, cached, or otherwise
+     filtered, after all filters
+     defined with the %def itself have been applied. Allows the
+     creation of default expression filters that let the output
+     of return-valued %defs "opt out" of that filtering via
+     passing special attributes or objects.
+    
+    :param cache_dir: Filesystem directory where cache files will be
+     placed.  See :ref:`caching_toplevel`.
+    
+    :param cache_enabled: Boolean flag which enables caching of this
+     template.  See :ref:`caching_toplevel`.
+    
+    :param cache_type: Type of Beaker caching to be applied to the 
+     template. See :ref:`caching_toplevel`.
+    
+    :param cache_url: URL of a memcached server with which to use
+     for caching.  See :ref:`caching_toplevel`.
+
+    :param default_filters: List of string filter names that will
+     be applied to all expressions.  See :ref:`filtering_default_filters`.
+
+    :param disable_unicode: Disables all awareness of Python Unicode
+     objects.  See :ref:`unicode_disabled`.
+
+    :param encoding_errors: Error parameter passed to ``encode()`` when
+     string encoding is performed. See :ref:`usage_unicode`.
+    
+    :param error_handler: Python callable which is called whenever
+     compile or runtime exceptions occur. The callable is passed
+     the current context as well as the exception. If the
+     callable returns ``True``, the exception is considered to
+     be handled, else it is re-raised after the function
+     completes. Is used to provide custom error-rendering
+     functions.
+    
+    :param format_exceptions: if ``True``, exceptions which occur during
+     the render phase of this template will be caught and
+     formatted into an HTML error page, which then becomes the
+     rendered result of the :meth:`render` call. Otherwise,
+     runtime exceptions are propagated outwards.
+     
+    :param imports: String list of Python statements, typically individual
+     "import" lines, which will be placed into the module level
+     preamble of all generated Python modules. See the example
+     in :ref:`filtering_default_filters`.
+
+    :param input_encoding: Encoding of the template's source code.  Can
+     be used in lieu of the coding comment. See
+     :ref:`usage_unicode` as well as :ref:`unicode_toplevel` for
+     details on source encoding.
+    
+    :param lookup: a :class:`.TemplateLookup` instance that will be used
+     for all file lookups via the ``<%namespace>``,
+     ``<%include>``, and ``<%inherit>`` tags. See
+     :ref:`usage_templatelookup`.
+    
+    :param module_directory: Filesystem location where generated 
+     Python module files will be placed.
+
+    :param module_filename: Overrides the filename of the generated 
+     Python module file. For advanced usage only.
+    
+    :param output_encoding: The encoding to use when :meth:`.render` 
+     is called. See :ref:`usage_unicode` as well as
+     :ref:`unicode_toplevel`.
+    
+    :param preprocessor: Python callable which will be passed 
+     the full template source before it is parsed. The return
+     result of the callable will be used as the template source
+     code.
+     
+    :param strict_undefined: Replaces the automatic usage of 
+     ``UNDEFINED`` for any undeclared variables not located in
+     the :class:`.Context` with an immediate raise of
+     ``NameError``. The advantage is immediate reporting of
+     missing variables which include the name. New in 0.3.6.
+    
+    :param uri: string uri or other identifier for this template.  
+     If not provided, the uri is generated from the filesystem
+     path, or from the in-memory identity of a non-file-based
+     template. The primary usage of the uri is to provide a key
+     within :class:`.TemplateLookup`, as well as to generate the
+     file path of the generated Python module file, if
+     ``module_directory`` is specified.
+    
+    """
+    
+    def __init__(self, 
+                    text=None, 
+                    filename=None, 
+                    uri=None, 
+                    format_exceptions=False, 
+                    error_handler=None, 
+                    lookup=None, 
+                    output_encoding=None, 
+                    encoding_errors='strict', 
+                    module_directory=None, 
+                    cache_type=None, 
+                    cache_dir=None, 
+                    cache_url=None, 
+                    module_filename=None, 
+                    input_encoding=None, 
+                    disable_unicode=False, 
+                    default_filters=None, 
+                    buffer_filters=(), 
+                    strict_undefined=False,
+                    imports=None, 
+                    preprocessor=None, 
+                    cache_enabled=True):
+        if uri:
+            self.module_id = re.sub(r'\W', "_", uri)
+            self.uri = uri
+        elif filename:
+            self.module_id = re.sub(r'\W', "_", filename)
+            drive, path = os.path.splitdrive(filename)
+            path = os.path.normpath(path).replace(os.path.sep, "/")
+            self.uri = path
+        else:
+            self.module_id = "memory:" + hex(id(self))
+            self.uri = self.module_id
+        
+        self.input_encoding = input_encoding
+        self.output_encoding = output_encoding
+        self.encoding_errors = encoding_errors
+        self.disable_unicode = disable_unicode
+        self.strict_undefined = strict_undefined
+
+        if util.py3k and disable_unicode:
+            raise exceptions.UnsupportedError(
+                                    "Mako for Python 3 does not "
+                                    "support disabling Unicode")
+        
+        if default_filters is None:
+            if util.py3k or self.disable_unicode:
+                self.default_filters = ['str']
+            else:
+                self.default_filters = ['unicode']
+        else:
+            self.default_filters = default_filters
+        self.buffer_filters = buffer_filters
+            
+        self.imports = imports
+        self.preprocessor = preprocessor
+        
+        # if plain text, compile code in memory only
+        if text is not None:
+            (code, module) = _compile_text(self, text, filename)
+            self._code = code
+            self._source = text
+            ModuleInfo(module, None, self, filename, code, text)
+        elif filename is not None:
+            # if template filename and a module directory, load
+            # a filesystem-based module file, generating if needed
+            if module_filename is not None:
+                path = module_filename
+            elif module_directory is not None:
+                u = self.uri
+                if u[0] == '/':
+                    u = u[1:]
+                path = os.path.abspath(
+                        os.path.join(
+                            os.path.normpath(module_directory), 
+                            os.path.normpath(u) + ".py"
+                            )
+                        )
+            else:
+                path = None
+                
+            module = self._compile_from_file(path, filename)
+        else:
+            raise exceptions.RuntimeException(
+                                "Template requires text or filename")
+
+        self.module = module
+        self.filename = filename
+        self.callable_ = self.module.render_body
+        self.format_exceptions = format_exceptions
+        self.error_handler = error_handler
+        self.lookup = lookup
+        self.cache_type = cache_type
+        self.cache_dir = cache_dir
+        self.cache_url = cache_url
+        self.cache_enabled = cache_enabled
+        
+    def _compile_from_file(self, path, filename):
+        if path is not None:
+            util.verify_directory(os.path.dirname(path))
+            filemtime = os.stat(filename)[stat.ST_MTIME]
+            if not os.path.exists(path) or \
+                        os.stat(path)[stat.ST_MTIME] < filemtime:
+                _compile_module_file(
+                            self, 
+                            open(filename, 'rb').read(), 
+                            filename, 
+                            path)
+            module = imp.load_source(self.module_id, path, open(path, 'rb'))
+            del sys.modules[self.module_id]
+            if module._magic_number != codegen.MAGIC_NUMBER:
+                _compile_module_file(
+                            self, 
+                            open(filename, 'rb').read(), 
+                            filename, 
+                            path)
+                module = imp.load_source(self.module_id, path, open(path, 'rb'))
+                del sys.modules[self.module_id]
+            ModuleInfo(module, path, self, filename, None, None)
+        else:
+            # template filename and no module directory, compile code
+            # in memory
+            code, module = _compile_text(
+                                self, 
+                                open(filename, 'rb').read(), 
+                                filename)
+            self._source = None
+            self._code = code
+            ModuleInfo(module, None, self, filename, code, None)
+        return module
+        
+    @property
+    def source(self):
+        """return the template source code for this Template."""
+        
+        return _get_module_info_from_callable(self.callable_).source
+
+    @property
+    def code(self):
+        """return the module source code for this Template"""
+        
+        return _get_module_info_from_callable(self.callable_).code
+    
+    @property
+    def cache(self):
+        return self.module._template_cache
+    
+    def render(self, *args, **data):
+        """Render the output of this template as a string.
+        
+        if the template specifies an output encoding, the string
+        will be encoded accordingly, else the output is raw (raw
+        output uses cStringIO and can't handle multibyte
+        characters). a Context object is created corresponding
+        to the given data. Arguments that are explictly declared
+        by this template's internal rendering method are also
+        pulled from the given \*args, \**data members.
+        
+        """
+        return runtime._render(self, self.callable_, args, data)
+    
+    def render_unicode(self, *args, **data):
+        """render the output of this template as a unicode object."""
+        
+        return runtime._render(self, 
+                                self.callable_, 
+                                args, 
+                                data, 
+                                as_unicode=True)
+        
+    def render_context(self, context, *args, **kwargs):
+        """Render this Template with the given context.  
+        
+        the data is written to the context's buffer.
+        
+        """
+        if getattr(context, '_with_template', None) is None:
+            context._with_template = self
+        runtime._render_context(self, 
+                                self.callable_, 
+                                context, 
+                                *args, 
+                                **kwargs)
+    
+    def has_def(self, name):
+        return hasattr(self.module, "render_%s" % name)
+        
+    def get_def(self, name):
+        """Return a def of this template as a :class:`.DefTemplate`."""
+        
+        return DefTemplate(self, getattr(self.module, "render_%s" % name))
+
+    def _get_def_callable(self, name):
+        return getattr(self.module, "render_%s" % name)
+    
+    @property
+    def last_modified(self): 
+        return self.module._modified_time    
+    
+class ModuleTemplate(Template):
+    """A Template which is constructed given an existing Python module.
+    
+        e.g.::
+        
+        t = Template("this is a template")
+        f = file("mymodule.py", "w")
+        f.write(t.code)
+        f.close()
+        
+        import mymodule
+        
+        t = ModuleTemplate(mymodule)
+        print t.render()
+    
+    """
+    
+    def __init__(self, module, 
+                        module_filename=None, 
+                        template=None, 
+                        template_filename=None, 
+                        module_source=None, 
+                        template_source=None,
+                        output_encoding=None, 
+                        encoding_errors='strict',
+                        disable_unicode=False, 
+                        format_exceptions=False,
+                        error_handler=None, 
+                        lookup=None, 
+                        cache_type=None,
+                        cache_dir=None, 
+                        cache_url=None, 
+                        cache_enabled=True
+    ):
+        self.module_id = re.sub(r'\W', "_", module._template_uri)
+        self.uri = module._template_uri
+        self.input_encoding = module._source_encoding
+        self.output_encoding = output_encoding
+        self.encoding_errors = encoding_errors
+        self.disable_unicode = disable_unicode
+        self.module = module
+        self.filename = template_filename
+        ModuleInfo(module, 
+                        module_filename, 
+                        self, 
+                        template_filename, 
+                        module_source, 
+                        template_source)
+        
+        self.callable_ = self.module.render_body
+        self.format_exceptions = format_exceptions
+        self.error_handler = error_handler
+        self.lookup = lookup
+        self.cache_type = cache_type
+        self.cache_dir = cache_dir
+        self.cache_url = cache_url
+        self.cache_enabled = cache_enabled
+        
+class DefTemplate(Template):
+    """a Template which represents a callable def in a parent
+    template."""
+    
+    def __init__(self, parent, callable_):
+        self.parent = parent
+        self.callable_ = callable_
+        self.output_encoding = parent.output_encoding
+        self.module = parent.module
+        self.encoding_errors = parent.encoding_errors
+        self.format_exceptions = parent.format_exceptions
+        self.error_handler = parent.error_handler
+        self.lookup = parent.lookup
+
+    def get_def(self, name):
+        return self.parent.get_def(name)
+
+class ModuleInfo(object):
+    """Stores information about a module currently loaded into
+    memory, provides reverse lookups of template source, module
+    source code based on a module's identifier.
+    
+     """
+    _modules = weakref.WeakValueDictionary()
+
+    def __init__(self, 
+                    module, 
+                    module_filename, 
+                    template, 
+                    template_filename, 
+                    module_source, 
+                    template_source):
+        self.module = module
+        self.module_filename = module_filename
+        self.template_filename = template_filename
+        self.module_source = module_source
+        self.template_source = template_source
+        self._modules[module.__name__] = template._mmarker = self
+        if module_filename:
+            self._modules[module_filename] = self
+    
+    @property
+    def code(self):
+        if self.module_source is not None:
+            return self.module_source
+        else:
+            return open(self.module_filename).read()
+    
+    @property
+    def source(self):
+        if self.template_source is not None:
+            if self.module._source_encoding and \
+                    not isinstance(self.template_source, str):
+                return self.template_source.decode(
+                                self.module._source_encoding)
+            else:
+                return self.template_source
+        else:
+            if self.module._source_encoding:
+                return open(self.template_filename, 'rb').read().\
+                                decode(self.module._source_encoding)
+            else:
+                return open(self.template_filename).read()
+        
+def _compile_text(template, text, filename):
+    identifier = template.module_id
+    lexer = Lexer(text, 
+                    filename, 
+                    disable_unicode=template.disable_unicode,
+                    input_encoding=template.input_encoding,
+                    preprocessor=template.preprocessor)
+    node = lexer.parse()
+    
+    source = codegen.compile(node, 
+                            template.uri, 
+                            filename,
+                            default_filters=template.default_filters,
+                            buffer_filters=template.buffer_filters, 
+                            imports=template.imports, 
+                            source_encoding=lexer.encoding,
+                            generate_magic_comment=template.disable_unicode,
+                            disable_unicode=template.disable_unicode,
+                            strict_undefined=template.strict_undefined)
+
+    cid = identifier
+    if not util.py3k and isinstance(cid, str):
+        cid = cid.encode()
+    module = types.ModuleType(cid)
+    code = compile(source, cid, 'exec')
+    exec(code, module.__dict__, module.__dict__)
+    return (source, module)
+
+def _compile_module_file(template, text, filename, outputpath):
+    identifier = template.module_id
+    lexer = Lexer(text, 
+                    filename, 
+                    disable_unicode=template.disable_unicode,
+                    input_encoding=template.input_encoding,
+                    preprocessor=template.preprocessor)
+                    
+    node = lexer.parse()
+    source = codegen.compile(node, 
+                                template.uri, 
+                                filename,
+                                default_filters=template.default_filters,
+                                buffer_filters=template.buffer_filters,
+                                imports=template.imports,
+                                source_encoding=lexer.encoding,
+                                generate_magic_comment=True,
+                                disable_unicode=template.disable_unicode,
+                                strict_undefined=template.strict_undefined)
+                                
+    # make tempfiles in the same location as the ultimate 
+    # location.   this ensures they're on the same filesystem,
+    # avoiding synchronization issues.
+    (dest, name) = tempfile.mkstemp(dir=os.path.dirname(outputpath))
+    
+    if isinstance(source, str):
+        source = source.encode(lexer.encoding or 'ascii')
+        
+    os.write(dest, source)
+    os.close(dest)
+    shutil.move(name, outputpath)
+
+def _get_module_info_from_callable(callable_):
+    return _get_module_info(callable_.__globals__['__name__'])
+    
+def _get_module_info(filename):
+    return ModuleInfo._modules[filename]
+        
diff --git a/lib3/mako-0.3.6/mako/util.py b/lib3/mako-0.3.6/mako/util.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/mako/util.py
@@ -0,0 +1,315 @@
+# util.py
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp at zzzcomputing.com
+#
+# This module is part of Mako and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+import sys
+
+
+py3k = getattr(sys, 'py3kwarning', False) or sys.version_info >= (3, 0)
+py24 = sys.version_info >= (2, 4) and sys.version_info < (2, 5)
+jython = sys.platform.startswith('java')
+win32 = sys.platform.startswith('win')
+
+if py3k:
+    from io import StringIO
+else:
+    try:
+        from io import StringIO
+    except:
+        from io import StringIO
+
+import codecs, re, weakref, os, time, operator
+
+try:
+    import threading
+    import _thread
+except ImportError:
+    import dummy_threading as threading
+    import _dummy_thread as thread
+
+if win32 or jython:
+    time_func = time.clock
+else:
+    time_func = time.time 
+   
+def function_named(fn, name):
+    """Return a function with a given __name__.
+
+    Will assign to __name__ and return the original function if possible on
+    the Python implementation, otherwise a new function will be constructed.
+
+    """
+    fn.__name__ = name
+    return fn
+
+try:
+    from functools import partial
+except:
+    def partial(func, *args, **keywords):
+        def newfunc(*fargs, **fkeywords):
+            newkeywords = keywords.copy()
+            newkeywords.update(fkeywords)
+            return func(*(args + fargs), **newkeywords)
+        return newfunc
+
+if py24:
+    def exception_name(exc):
+        try:
+            return exc.__class__.__name__
+        except AttributeError:
+            return exc.__name__
+else:
+    def exception_name(exc):
+        return exc.__class__.__name__
+    
+def verify_directory(dir):
+    """create and/or verify a filesystem directory."""
+    
+    tries = 0
+    
+    while not os.path.exists(dir):
+        try:
+            tries += 1
+            os.makedirs(dir, 0o775)
+        except:
+            if tries > 5:
+                raise
+
+def to_list(x, default=None):
+    if x is None:
+        return default
+    if not isinstance(x, (list, tuple)):
+        return [x]
+    else:
+        return x
+
+
+    
+
+
+class SetLikeDict(dict):
+    """a dictionary that has some setlike methods on it"""
+    def union(self, other):
+        """produce a 'union' of this dict and another (at the key level).
+        
+        values in the second dict take precedence over that of the first"""
+        x = SetLikeDict(**self)
+        x.update(other)
+        return x
+
+class FastEncodingBuffer(object):
+    """a very rudimentary buffer that is faster than StringIO, 
+    but doesnt crash on unicode data like cStringIO."""
+    
+    def __init__(self, encoding=None, errors='strict', str=False):
+        self.data = []
+        self.encoding = encoding
+        if str:
+            self.delim = ''
+        else:
+            self.delim = ''
+        self.str = str
+        self.errors = errors
+        self.write = self.data.append
+    
+    def truncate(self):
+        self.data =[]
+        
+    def getvalue(self):
+        if self.encoding:
+            return self.delim.join(self.data).encode(self.encoding, self.errors)
+        else:
+            return self.delim.join(self.data)
+
+class LRUCache(dict):
+    """A dictionary-like object that stores a limited number of items, discarding
+    lesser used items periodically.
+    
+    this is a rewrite of LRUCache from Myghty to use a periodic timestamp-based
+    paradigm so that synchronization is not really needed.  the size management 
+    is inexact.
+    """
+    
+    class _Item(object):
+        def __init__(self, key, value):
+            self.key = key
+            self.value = value
+            self.timestamp = time_func()
+        def __repr__(self):
+            return repr(self.value)
+    
+    def __init__(self, capacity, threshold=.5):
+        self.capacity = capacity
+        self.threshold = threshold
+    
+    def __getitem__(self, key):
+        item = dict.__getitem__(self, key)
+        item.timestamp = time_func()
+        return item.value
+    
+    def values(self):
+        return [i.value for i in dict.values(self)]
+    
+    def setdefault(self, key, value):
+        if key in self:
+            return self[key]
+        else:
+            self[key] = value
+            return value
+    
+    def __setitem__(self, key, value):
+        item = dict.get(self, key)
+        if item is None:
+            item = self._Item(key, value)
+            dict.__setitem__(self, key, item)
+        else:
+            item.value = value
+        self._manage_size()
+    
+    def _manage_size(self):
+        while len(self) > self.capacity + self.capacity * self.threshold:
+            bytime = sorted(dict.values(self), 
+                            key=operator.attrgetter('timestamp'), reverse=True)
+            for item in bytime[self.capacity:]:
+                try:
+                    del self[item.key]
+                except KeyError:
+                    # if we couldnt find a key, most likely some other thread broke in 
+                    # on us. loop around and try again
+                    break
+
+# Regexp to match python magic encoding line
+_PYTHON_MAGIC_COMMENT_re = re.compile(
+    r'[ \t\f]* \# .* coding[=:][ \t]*([-\w.]+)',
+    re.VERBOSE)
+
+def parse_encoding(fp):
+    """Deduce the encoding of a Python source file (binary mode) from magic comment.
+
+    It does this in the same way as the `Python interpreter`__
+
+    .. __: http://docs.python.org/ref/encodings.html
+
+    The ``fp`` argument should be a seekable file object in binary mode.
+    """
+    pos = fp.tell()
+    fp.seek(0)
+    try:
+        line1 = fp.readline()
+        has_bom = line1.startswith(codecs.BOM_UTF8)
+        if has_bom:
+            line1 = line1[len(codecs.BOM_UTF8):]
+
+        m = _PYTHON_MAGIC_COMMENT_re.match(line1.decode('ascii', 'ignore'))
+        if not m:
+            try:
+                import parser
+                parser.suite(line1.decode('ascii', 'ignore'))
+            except (ImportError, SyntaxError):
+                # Either it's a real syntax error, in which case the source
+                # is not valid python source, or line2 is a continuation of
+                # line1, in which case we don't want to scan line2 for a magic
+                # comment.
+                pass
+            else:
+                line2 = fp.readline()
+                m = _PYTHON_MAGIC_COMMENT_re.match(line2.decode('ascii', 'ignore'))
+
+        if has_bom:
+            if m:
+                raise SyntaxError("python refuses to compile code with both a UTF8" \
+                      " byte-order-mark and a magic encoding comment")
+            return 'utf_8'
+        elif m:
+            return m.group(1)
+        else:
+            return None
+    finally:
+        fp.seek(pos)
+
+def sorted_dict_repr(d):
+    """repr() a dictionary with the keys in order.
+    
+    Used by the lexer unit test to compare parse trees based on strings.
+    
+    """
+    keys = list(d.keys())
+    keys.sort()
+    return "{" + ", ".join(["%r: %r" % (k, d[k]) for k in keys]) + "}"
+    
+def restore__ast(_ast):
+    """Attempt to restore the required classes to the _ast module if it
+    appears to be missing them
+    """
+    if hasattr(_ast, 'AST'):
+        return
+    _ast.PyCF_ONLY_AST = 2 << 9
+    m = compile("""\
+def foo(): pass
+class Bar(object): pass
+if False: pass
+baz = 'mako'
+1 + 2 - 3 * 4 / 5
+6 // 7 % 8 << 9 >> 10
+11 & 12 ^ 13 | 14
+15 and 16 or 17
+-baz + (not +18) - ~17
+baz and 'foo' or 'bar'
+(mako is baz == baz) is not baz != mako
+mako > baz < mako >= baz <= mako
+mako in baz not in mako""", '<unknown>', 'exec', _ast.PyCF_ONLY_AST)
+    _ast.Module = type(m)
+
+    for cls in _ast.Module.__mro__:
+        if cls.__name__ == 'mod':
+            _ast.mod = cls
+        elif cls.__name__ == 'AST':
+            _ast.AST = cls
+
+    _ast.FunctionDef = type(m.body[0])
+    _ast.ClassDef = type(m.body[1])
+    _ast.If = type(m.body[2])
+
+    _ast.Name = type(m.body[3].targets[0])
+    _ast.Store = type(m.body[3].targets[0].ctx)
+    _ast.Str = type(m.body[3].value)
+
+    _ast.Sub = type(m.body[4].value.op)
+    _ast.Add = type(m.body[4].value.left.op)
+    _ast.Div = type(m.body[4].value.right.op)
+    _ast.Mult = type(m.body[4].value.right.left.op)
+
+    _ast.RShift = type(m.body[5].value.op)
+    _ast.LShift = type(m.body[5].value.left.op)
+    _ast.Mod = type(m.body[5].value.left.left.op)
+    _ast.FloorDiv = type(m.body[5].value.left.left.left.op)
+
+    _ast.BitOr = type(m.body[6].value.op)
+    _ast.BitXor = type(m.body[6].value.left.op)
+    _ast.BitAnd = type(m.body[6].value.left.left.op)
+
+    _ast.Or = type(m.body[7].value.op)
+    _ast.And = type(m.body[7].value.values[0].op)
+
+    _ast.Invert = type(m.body[8].value.right.op)
+    _ast.Not = type(m.body[8].value.left.right.op)
+    _ast.UAdd = type(m.body[8].value.left.right.operand.op)
+    _ast.USub = type(m.body[8].value.left.left.op)
+
+    _ast.Or = type(m.body[9].value.op)
+    _ast.And = type(m.body[9].value.values[0].op)
+
+    _ast.IsNot = type(m.body[10].value.ops[0])
+    _ast.NotEq = type(m.body[10].value.ops[1])
+    _ast.Is = type(m.body[10].value.left.ops[0])
+    _ast.Eq = type(m.body[10].value.left.ops[1])
+
+    _ast.Gt = type(m.body[11].value.ops[0])
+    _ast.Lt = type(m.body[11].value.ops[1])
+    _ast.GtE = type(m.body[11].value.ops[2])
+    _ast.LtE = type(m.body[11].value.ops[3])
+
+    _ast.In = type(m.body[12].value.ops[0])
+    _ast.NotIn = type(m.body[12].value.ops[1])
diff --git a/lib3/mako-0.3.6/scripts/mako-render b/lib3/mako-0.3.6/scripts/mako-render
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/scripts/mako-render
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+def render(data):
+    from mako.template import Template
+    from mako.lookup import TemplateLookup
+
+    lookup = TemplateLookup(["."])
+    return Template(data, lookup=lookup).render()
+
+def main(argv=None):
+    from os.path import isfile
+    from sys import stdin
+
+    if argv is None:
+        import sys
+        argv = sys.argv
+
+    from optparse import OptionParser
+
+    parser = OptionParser("usage: %prog [FILENAME]")
+
+    opts, args = parser.parse_args(argv[1:])
+    if len(args) not in (0, 1):
+        parser.error("wrong number of arguments") # Will exit
+
+    if (len(args) == 0) or (args[0] == "-"):
+        fo = stdin
+    else:
+        filename = args[0]
+        if not isfile(filename):
+            raise SystemExit("error: can't find %s" % filename)
+        fo = open(filename)
+
+    data = fo.read()
+    print render(data)
+
+if __name__ == "__main__":
+    main()
diff --git a/lib3/mako-0.3.6/setup.cfg b/lib3/mako-0.3.6/setup.cfg
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/setup.cfg
@@ -0,0 +1,2 @@
+[egg_info]
+tag_build = dev
diff --git a/lib3/mako-0.3.6/setup.py b/lib3/mako-0.3.6/setup.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/setup.py
@@ -0,0 +1,68 @@
+from setuptools import setup, find_packages
+import os
+import re
+import sys
+
+extra = {}
+if sys.version_info >= (3, 0):
+    extra.update(
+        use_2to3=True,
+    )
+
+v = open(os.path.join(os.path.dirname(__file__), 'mako', '__init__.py'))
+VERSION = re.compile(r".*__version__ = '(.*?)'", re.S).match(v.read()).group(1)
+v.close()
+
+setup(name='Mako',
+      version=VERSION,
+      description="A super-fast templating language that borrows the \
+ best ideas from the existing templating languages.",
+      long_description="""\
+Mako is a template library written in Python. It provides a familiar, non-XML 
+syntax which compiles into Python modules for maximum performance. Mako's 
+syntax and API borrows from the best ideas of many others, including Django
+templates, Cheetah, Myghty, and Genshi. Conceptually, Mako is an embedded 
+Python (i.e. Python Server Page) language, which refines the familiar ideas
+of componentized layout and inheritance to produce one of the most 
+straightforward and flexible models available, while also maintaining close 
+ties to Python calling and scoping semantics.
+
+""",
+      classifiers=[
+      'Development Status :: 5 - Production/Stable',
+      'Environment :: Web Environment',
+      'Intended Audience :: Developers',
+      'Programming Language :: Python',
+      'Programming Language :: Python :: 3',
+      'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
+      ],
+      keywords='wsgi myghty mako',
+      author='Mike Bayer',
+      author_email='mike at zzzcomputing.com',
+      url='http://www.makotemplates.org/',
+      license='MIT',
+      packages=find_packages('.', exclude=['examples*', 'test*']),
+      scripts=['scripts/mako-render'],
+      tests_require = ['nose >= 0.11'],
+      test_suite = "nose.collector",
+      zip_safe=False,
+      install_requires=[
+          'MarkupSafe>=0.9.2',
+      ],
+      extras_require = {'beaker':['Beaker>=1.1']},
+      entry_points="""
+      [python.templating.engines]
+      mako = mako.ext.turbogears:TGPlugin
+      
+      [pygments.lexers]
+      mako = mako.ext.pygmentplugin:MakoLexer
+      html+mako = mako.ext.pygmentplugin:MakoHtmlLexer
+      xml+mako = mako.ext.pygmentplugin:MakoXmlLexer
+      js+mako = mako.ext.pygmentplugin:MakoJavascriptLexer
+      css+mako = mako.ext.pygmentplugin:MakoCssLexer
+
+      [babel.extractors]
+      mako = mako.ext.babelplugin:extract
+      """,
+      **extra
+)
diff --git a/lib3/mako-0.3.6/test/__init__.py b/lib3/mako-0.3.6/test/__init__.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/__init__.py
@@ -0,0 +1,93 @@
+from mako.template import Template
+import unittest, os
+from mako.util import function_named, py3k
+import re
+
+from nose import SkipTest
+
+
+template_base = os.path.join(os.path.dirname(__file__), 'templates')
+module_base = os.path.join(template_base, 'modules')
+
+class TemplateTest(unittest.TestCase):
+    
+    def _file_template(self, filename, **kw):
+        filepath = self._file_path(filename)
+        return Template(uri=filename, filename=filepath,
+                            module_directory=module_base, **kw)
+    
+    def _file_path(self, filename):
+        name, ext = os.path.splitext(filename)
+        
+        if py3k:
+            py3k_path = os.path.join(template_base, name + "_py3k" + ext)
+            if os.path.exists(py3k_path):
+                return py3k_path
+        
+        return os.path.join(template_base, filename)
+        
+    def _do_file_test(self, filename, expected, filters=None, 
+                        unicode_=True, template_args=None, **kw):
+        t1 = self._file_template(filename, **kw)
+        self._do_test(t1, expected, filters=filters, 
+                        unicode_=unicode_, template_args=template_args)
+    
+    def _do_memory_test(self, source, expected, filters=None, 
+                        unicode_=True, template_args=None, **kw):
+        t1 = Template(text=source, **kw)
+        self._do_test(t1, expected, filters=filters, 
+                        unicode_=unicode_, template_args=template_args)
+    
+    def _do_test(self, template, expected, filters=None, template_args=None, unicode_=True):
+        if template_args is None:
+            template_args = {}
+        if unicode_:
+            output = template.render_unicode(**template_args)
+        else:
+            output = template.render(**template_args)
+            
+        if filters:
+            output = filters(output)
+        eq_(output, expected)
+    
+def eq_(a, b, msg=None):
+    """Assert a == b, with repr messaging on failure."""
+    assert a == b, msg or "%r != %r" % (a, b)
+
+def teardown():
+    import shutil
+    shutil.rmtree(module_base, True)
+
+def assert_raises(except_cls, callable_, *args, **kw):
+    try:
+        callable_(*args, **kw)
+        success = False
+    except except_cls as e:
+        success = True
+    
+    # assert outside the block so it works for AssertionError too !
+    assert success, "Callable did not raise an exception"
+
+def assert_raises_message(except_cls, msg, callable_, *args, **kwargs):
+    try:
+        callable_(*args, **kwargs)
+        assert False, "Callable did not raise an exception"
+    except except_cls as e:
+        assert re.search(msg, str(e)), "%r !~ %s" % (msg, e)
+        print(str(e))
+
+def skip_if(predicate, reason=None):
+    """Skip a test if predicate is true."""
+    reason = reason or predicate.__name__
+
+    def decorate(fn):
+        fn_name = fn.__name__
+        def maybe(*args, **kw):
+            if predicate():
+                msg = "'%s' skipped: %s" % (
+                    fn_name, reason)
+                raise SkipTest(msg)
+            else:
+                return fn(*args, **kw)
+        return function_named(maybe, fn_name)
+    return decorate
diff --git a/lib3/mako-0.3.6/test/foo/test_ns.py b/lib3/mako-0.3.6/test/foo/test_ns.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/foo/test_ns.py
@@ -0,0 +1,7 @@
+def foo1(context):
+    context.write("this is foo1.")
+    return ''
+    
+def foo2(context, x):
+    context.write("this is foo2, x is " + x)
+    return ''
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/sample_module_namespace.py b/lib3/mako-0.3.6/test/sample_module_namespace.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/sample_module_namespace.py
@@ -0,0 +1,7 @@
+def foo1(context):
+    context.write("this is foo1.")
+    return ''
+    
+def foo2(context, x):
+    context.write("this is foo2, x is " + x)
+    return ''
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/badbom.html b/lib3/mako-0.3.6/test/templates/badbom.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/badbom.html
@@ -0,0 +1,2 @@
+## -*- coding: ascii -*-
+Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/bom.html b/lib3/mako-0.3.6/test/templates/bom.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/bom.html
@@ -0,0 +1,1 @@
+Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/bommagic.html b/lib3/mako-0.3.6/test/templates/bommagic.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/bommagic.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/chs_unicode.html b/lib3/mako-0.3.6/test/templates/chs_unicode.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/chs_unicode.html
@@ -0,0 +1,11 @@
+## -*- encoding:utf8 -*-
+<%
+ msg = u'新中国的主席'
+%>
+
+<%def name="welcome(who, place=u'北京')">
+Welcome ${who} to ${place}.
+</%def>
+
+${name} 是 ${msg}<br/>
+${welcome(u'ä½ ')}
diff --git a/lib3/mako-0.3.6/test/templates/chs_unicode_py3k.html b/lib3/mako-0.3.6/test/templates/chs_unicode_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/chs_unicode_py3k.html
@@ -0,0 +1,11 @@
+## -*- encoding:utf8 -*-
+<%
+ msg = '新中国的主席'
+%>
+
+<%def name="welcome(who, place='北京')">
+Welcome ${who} to ${place}.
+</%def>
+
+${name} 是 ${msg}<br/>
+${welcome('ä½ ')}
diff --git a/lib3/mako-0.3.6/test/templates/chs_utf8.html b/lib3/mako-0.3.6/test/templates/chs_utf8.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/chs_utf8.html
@@ -0,0 +1,17 @@
+## -*- encoding:utf8 -*-
+<%
+ msg = '新中国的主席'
+%>
+
+<%def name="welcome(who, place='北京')">
+Welcome ${who} to ${place}.
+</%def>
+
+<%def name="welcome_buffered(who, place='北京')" buffered="True">
+Welcome ${who} to ${place}.
+</%def>
+
+${name} 是 ${msg}<br/>
+${welcome('ä½ ')}
+${welcome_buffered('ä½ ')}
+
diff --git a/lib3/mako-0.3.6/test/templates/crlf.html b/lib3/mako-0.3.6/test/templates/crlf.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/crlf.html
@@ -0,0 +1,19 @@
+<html>
+
+<%page args="a=['foo',
+                'bar']"/>
+
+like the name says.
+
+    % for x in [1,2,3]:
+        ${x}\
+    % endfor
+
+${trumpeter == 'Miles' and trumpeter or \
+      'Dizzy'}
+
+<%def name="hi()">
+    hi!
+</%def>
+
+</html>
diff --git a/lib3/mako-0.3.6/test/templates/foo/modtest.html.py b/lib3/mako-0.3.6/test/templates/foo/modtest.html.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/foo/modtest.html.py
@@ -0,0 +1,25 @@
+from mako import runtime, filters, cache
+UNDEFINED = runtime.UNDEFINED
+__M_dict_builtin = dict
+__M_locals_builtin = locals
+_magic_number = 5
+_modified_time = 1267565427.7968459
+_template_filename='/Users/classic/dev/mako/test/templates/modtest.html'
+_template_uri='/modtest.html'
+_template_cache=cache.Cache(__name__, _modified_time)
+_source_encoding=None
+_exports = []
+
+
+def render_body(context,**pageargs):
+    context.caller_stack._push_frame()
+    try:
+        __M_locals = __M_dict_builtin(pageargs=pageargs)
+        __M_writer = context.writer()
+        # SOURCE LINE 1
+        __M_writer('this is a test')
+        return ''
+    finally:
+        context.caller_stack._pop_frame()
+
+
diff --git a/lib3/mako-0.3.6/test/templates/gettext.mako b/lib3/mako-0.3.6/test/templates/gettext.mako
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/gettext.mako
@@ -0,0 +1,83 @@
+<%page args="x, y=_('Page arg 1'), z=_('Page arg 2')"/>
+<%!
+import random
+def gettext(message): return message
+_ = gettext
+def ungettext(s, p, c):
+    if c == 1:
+        return s
+    return p
+top = gettext('Begin')
+%>
+<%
+   # TRANSLATOR: Hi there!
+   hithere = _('Hi there!')
+
+   # TRANSLATOR: you should not be seeing this in the .po
+   rows = [[v for v in range(0,10)] for row in range(0,10)]
+
+   hello = _('Hello')
+%>
+<div id="header">
+  ${_('Welcome')}
+</div>
+<table>
+    % for row in (hithere, hello, _('Yo')):
+        ${makerow(row)}
+    % endfor
+    ${makerow(count=2)}
+</table>
+
+
+<div id="main">
+
+## TRANSLATOR: Ensure so and
+## so, thanks
+  ${_('The')} fuzzy ${ungettext('bunny', 'bunnies', random.randint(1, 2))}
+</div>
+
+<div id="footer">
+  ## TRANSLATOR: Good bye
+  ${_('Goodbye')}
+</div>
+   
+<%def name="makerow(row=_('Babel'), count=1)">
+    <!-- ${ungettext('hella', 'hellas', count)} -->
+    % for i in range(count):
+      <tr>
+      % for name in row:
+          <td>${name}</td>\
+      % endfor
+      </tr>
+    % endfor
+</%def>
+
+<%def name="comment()">
+  <!-- ${caller.body()} -->
+</%def>
+
+<%call expr="comment">
+  P.S.
+  ## TRANSLATOR: HTML comment
+  ${_('Goodbye, really!')}
+</%call>
+
+<!-- ${_('P.S. byebye')} -->
+
+<div id="end">
+  <a href="#top">
+    ## TRANSLATOR: you won't see this either
+    
+    ${_('Top')}
+  </a>
+</div>
+
+<%def name="panel()">
+
+${_(u'foo')} <%self:block_tpl title="123", name="_(u'baz')">
+
+${_(u'bar')}
+
+</%self:block_tpl>
+
+</%def>
diff --git a/lib3/mako-0.3.6/test/templates/index.html b/lib3/mako-0.3.6/test/templates/index.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/index.html
@@ -0,0 +1,1 @@
+this is index
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/internationalization.html b/lib3/mako-0.3.6/test/templates/internationalization.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/internationalization.html
@@ -0,0 +1,920 @@
+<div class="rst-docs">
+  
+  <h1 class="pudge-member-page-heading">Internationalization, Localization and Unicode</h1>
+  
+  <table rules="none" frame="void" class="docinfo">
+<col class="docinfo-name"></col>
+<col class="docinfo-content"></col>
+<tbody valign="top">
+<tr><th class="docinfo-name">Author:</th>
+<td>James Gardner</td></tr>
+<tr class="field"><th class="docinfo-name">updated:</th><td class="field-body">2006-12-11</td>
+</tr>
+</tbody>
+</table>
+
+  <div class="note">
+<p class="first admonition-title">Note</p>
+<p>This is a work in progress. We hope the internationalization, localization
+and Unicode support in Pylons is now robust and flexible but we would
+appreciate hearing about any issues we have. Just drop a line to the
+pylons-discuss mailing list on Google Groups.</p>
+<p class="last">This is the first draft of the full document including Unicode. Expect
+some typos and spelling mistakes!</p>
+</div>
+<div class="contents topic">
+<p class="topic-title first"><a id="table-of-contents" name="table-of-contents">Table of Contents</a></p>
+<ul class="auto-toc simple">
+<li><a href="#understanding-unicode" id="id1" name="id1" class="reference">1   Understanding Unicode</a><ul class="auto-toc">
+<li><a href="#what-is-unicode" id="id2" name="id2" class="reference">1.1   What is Unicode?</a></li>
+<li><a href="#unicode-in-python" id="id3" name="id3" class="reference">1.2   Unicode in Python</a></li>
+<li><a href="#unicode-literals-in-python-source-code" id="id4" name="id4" class="reference">1.3   Unicode Literals in Python Source Code</a></li>
+<li><a href="#input-and-output" id="id5" name="id5" class="reference">1.4   Input and Output</a></li>
+<li><a href="#unicode-filenames" id="id6" name="id6" class="reference">1.5   Unicode Filenames</a></li>
+</ul>
+</li>
+<li><a href="#applying-this-to-web-programming" id="id7" name="id7" class="reference">2   Applying this to Web Programming</a><ul class="auto-toc">
+<li><a href="#request-parameters" id="id8" name="id8" class="reference">2.1   Request Parameters</a></li>
+<li><a href="#templating" id="id9" name="id9" class="reference">2.2   Templating</a></li>
+<li><a href="#output-encoding" id="id10" name="id10" class="reference">2.3   Output Encoding</a></li>
+<li><a href="#databases" id="id11" name="id11" class="reference">2.4   Databases</a></li>
+</ul>
+</li>
+<li><a href="#internationalization-and-localization" id="id12" name="id12" class="reference">3   Internationalization and Localization</a><ul class="auto-toc">
+<li><a href="#getting-started" id="id13" name="id13" class="reference">3.1   Getting Started</a></li>
+<li><a href="#testing-the-application" id="id14" name="id14" class="reference">3.2   Testing the Application</a></li>
+<li><a href="#missing-translations" id="id15" name="id15" class="reference">3.3   Missing Translations</a></li>
+<li><a href="#translations-within-templates" id="id16" name="id16" class="reference">3.4   Translations Within Templates</a></li>
+<li><a href="#producing-a-python-egg" id="id17" name="id17" class="reference">3.5   Producing a Python Egg</a></li>
+<li><a href="#plural-forms" id="id18" name="id18" class="reference">3.6   Plural Forms</a></li>
+</ul>
+</li>
+<li><a href="#summary" id="id19" name="id19" class="reference">4   Summary</a></li>
+<li><a href="#further-reading" id="id20" name="id20" class="reference">5   Further Reading</a></li>
+</ul>
+</div>
+<p>Internationalization and localization are means of adapting software for
+non-native environments, especially for other nations and cultures.</p>
+<p>Parts of an application which might need to be localized might include:</p>
+<blockquote>
+<ul class="simple">
+<li>Language</li>
+<li>Date/time format</li>
+<li>Formatting of numbers e.g. decimal points, positioning of separators,
+character used as separator</li>
+<li>Time zones (UTC in internationalized environments)</li>
+<li>Currency</li>
+<li>Weights and measures</li>
+</ul>
+</blockquote>
+<p>The distinction between internationalization and localization is subtle but
+important. Internationalization is the adaptation of products for potential use
+virtually everywhere, while localization is the addition of special features
+for use in a specific locale.</p>
+<p>For example, in terms of language used in software, internationalization is the
+process of marking up all strings that might need to be translated whilst
+localization is the process of producing translations for a particular locale.</p>
+<p>Pylons provides built-in support to enable you to internationalize language but
+leaves you to handle any other aspects of internationalization which might be
+appropriate to your application.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Internationalization is often abbreviated as I18N (or i18n or I18n) where the
+number 18 refers to the number of letters omitted.
+Localization is often abbreviated L10n or l10n in the same manner. These
+abbreviations also avoid picking one spelling (internationalisation vs.
+internationalization, etc.) over the other.</p>
+</div>
+<p>In order to represent characters from multiple languages, you will need to use
+Unicode so this documentation will start with a description of why Unicode is
+useful, its history and how to use Unicode in Python.</p>
+<div class="section">
+<h1><a href="#id1" id="understanding-unicode" name="understanding-unicode" class="toc-backref">1   Understanding Unicode</a></h1>
+<p>If you've ever come across text in a foreign language that contains lots of
+<tt class="docutils literal"><span class="pre">????</span></tt> characters or have written some Python code and received a message
+such as <tt class="docutils literal"><span class="pre">UnicodeDecodeError:</span> <span class="pre">'ascii'</span> <span class="pre">codec</span> <span class="pre">can't</span> <span class="pre">decode</span> <span class="pre">byte</span> <span class="pre">0xff</span> <span class="pre">in</span> <span class="pre">position</span>
+<span class="pre">6:</span> <span class="pre">ordinal</span> <span class="pre">not</span> <span class="pre">in</span> <span class="pre">range(128)</span></tt> then you have run into a problem with character
+sets, encodings, Unicode and the like.</p>
+<p>The truth is that many developers are put off by Unicode because most of the
+time it is possible to muddle through rather than take the time to learn the
+basics. To make the problem worse if you have a system that manages to fudge
+the issues and just about work and then start trying to do things properly with
+Unicode it often highlights problems in other parts of your code.</p>
+<p>The good news is that Python has great Unicode support, so the rest of
+this article will show you how to correctly use Unicode in Pylons to avoid
+unwanted <tt class="docutils literal"><span class="pre">?</span></tt> characters and <tt class="docutils literal"><span class="pre">UnicodeDecodeErrors</span></tt>.</p>
+<div class="section">
+<h2><a href="#id2" id="what-is-unicode" name="what-is-unicode" class="toc-backref">1.1   What is Unicode?</a></h2>
+<p>When computers were first being used the characters that were most important
+were unaccented English letters. Each of these letters could be represented by
+a number between 32 and 127 and thus was born ASCII, a character set where
+space was 32, the letter "A" was 65 and everything could be stored in 7 bits.</p>
+<p>Most computers in those days were using 8-bit bytes so people quickly realized
+that they could use the codes 128-255 for their own purposes. Different people
+used the codes 128-255 to represent different characters and before long these
+different sets of characters were also standardized into <em>code pages</em>. This
+meant that if you needed some non-ASCII characters in a document you could also
+specify a codepage which would define which extra characters were available.
+For example Israel DOS used a code page called 862, while Greek users used 737.
+This just about worked for Western languages provided you didn't want to write
+an Israeli document with Greek characters but it didn't work at all for Asian
+languages where there are many more characters than can be represented in 8
+bits.</p>
+<p>Unicode is a character set that solves these problems by uniquely defining
+<em>every</em> character that is used anywhere in the world. Rather than defining a
+character as a particular combination of bits in the way ASCII does, each
+character is assigned a <em>code point</em>. For example the word <tt class="docutils literal"><span class="pre">hello</span></tt> is made
+from code points <tt class="docutils literal"><span class="pre">U+0048</span> <span class="pre">U+0065</span> <span class="pre">U+006C</span> <span class="pre">U+006C</span> <span class="pre">U+006F</span></tt>. The full list of code
+points can be found at <a href="http://www.unicode.org/charts/" class="reference">http://www.unicode.org/charts/</a>.</p>
+<p>There are lots of different ways of encoding Unicode code points into bits but
+the most popular encoding is UTF-8. Using UTF-8, every code point from 0-127 is
+stored in a single byte. Only code points 128 and above are stored using 2, 3,
+in fact, up to 6 bytes. This has the useful side effect that English text looks
+exactly the same in UTF-8 as it did in ASCII, because for every
+ASCII character with hexadecimal value 0xXY, the corresponding Unicode
+code point is U+00XY. This backwards compatibility is why if you are developing
+an application that is only used by English speakers you can often get away
+without handling characters properly and still expect things to work most of
+the time. Of course, if you use a different encoding such as UTF-16 this
+doesn't apply since none of the code points are encoded to 8 bits.</p>
+<p>The important things to note from the discussion so far are that:</p>
+<ul>
+<li><p class="first">Unicode can represent pretty much any character in any writing system in
+widespread use today</p>
+</li>
+<li><p class="first">Unicode uses code points to represent characters and the way these map to bits
+in memory depends on the encoding</p>
+</li>
+<li><dl class="first docutils">
+<dt>The most popular encoding is UTF-8 which has  several convenient properties:</dt>
+<dd><ol class="first last arabic simple">
+<li>It can handle any Unicode code point</li>
+<li>A Unicode string is turned into a string of bytes containing no embedded
+zero bytes. This avoids byte-ordering issues, and means UTF-8 strings can be
+processed by C functions such as strcpy() and sent through protocols that can't
+handle zero bytes</li>
+<li>A string of ASCII text is also valid UTF-8 text</li>
+<li>UTF-8 is fairly compact; the majority of code points are turned into two
+bytes, and values less than 128 occupy only a single byte.</li>
+<li>If bytes are corrupted or lost, it's possible to determine the start of
+the next UTF-8-encoded code point and resynchronize.</li>
+</ol>
+</dd>
+</dl>
+</li>
+</ul>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Since Unicode 3.1, some extensions have even been defined so that the
+defined range is now U+000000 to U+10FFFF (21 bits), and formally, the
+character set is defined as 31-bits to allow for future expansion. It is a myth
+that there are 65,536 Unicode code points and that every Unicode letter can
+really be squeezed into two bytes. It is also incorrect to think that UTF-8 can
+represent less characters than UTF-16. UTF-8 simply uses a variable number of
+bytes for a character, sometimes just one byte (8 bits).</p>
+</div>
+</div>
+<div class="section">
+<h2><a href="#id3" id="unicode-in-python" name="unicode-in-python" class="toc-backref">1.2   Unicode in Python</a></h2>
+<p>In Python Unicode strings are expressed as instances of the built-in
+<tt class="docutils literal"><span class="pre">unicode</span></tt> type. Under the hood, Python represents Unicode strings as either
+16 or 32 bit integers, depending on how the Python interpreter was compiled.</p>
+<p>The <tt class="docutils literal"><span class="pre">unicode()</span></tt> constructor has the signature <tt class="docutils literal"><span class="pre">unicode(string[,</span> <span class="pre">encoding,</span>
+<span class="pre">errors])</span></tt>. All of its arguments should be 8-bit strings. The first argument is
+converted to Unicode using the specified encoding; if you leave off the
+encoding argument, the ASCII encoding is used for the conversion, so characters
+greater than 127 will be treated as errors:</p>
+<pre class="literal-block">
+>>> unicode('hello')
+u'hello'
+>>> s = unicode('hello')
+>>> type(s)
+<type 'unicode'>
+>>> unicode('hello' + chr(255))
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6:
+                    ordinal not in range(128)
+</pre>
+<p>The <tt class="docutils literal"><span class="pre">errors</span></tt> argument specifies what to do if the string can't be decoded to
+ascii. Legal values for this argument are <tt class="docutils literal"><span class="pre">'strict'</span></tt> (raise a
+<tt class="docutils literal"><span class="pre">UnicodeDecodeError</span></tt> exception), <tt class="docutils literal"><span class="pre">'replace'</span></tt> (replace the character that
+can't be decoded with another one), or <tt class="docutils literal"><span class="pre">'ignore'</span></tt> (just leave the character
+out of the Unicode result).</p>
+<blockquote>
+<pre class="doctest-block">
+>>> unicode('\x80abc', errors='strict')
+Traceback (most recent call last):
+  File "<stdin>", line 1, in ?
+UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0:
+                    ordinal not in range(128)
+>>> unicode('\x80abc', errors='replace')
+u'\ufffdabc'
+>>> unicode('\x80abc', errors='ignore')
+u'abc'
+</pre>
+</blockquote>
+<p>It is important to understand the difference between <em>encoding</em> and <em>decoding</em>.
+Unicode strings are considered to be the Unicode code points but any
+representation of the Unicode string has to be encoded to something else, for
+example UTF-8 or ASCII. So when you are converting an ASCII or UTF-8 string to
+Unicode you are <em>decoding</em> it and when you are converting from Unicode to UTF-8
+or ASCII you are <em>encoding</em> it. This is why the error in the example above says
+that the ASCII codec cannot decode the byte <tt class="docutils literal"><span class="pre">0x80</span></tt> from ASCII to Unicode
+because it is not in the range(128) or 0-127. In fact <tt class="docutils literal"><span class="pre">0x80</span></tt> is hex for 128
+which the first number outside the ASCII range. However if we tell Python that
+the character <tt class="docutils literal"><span class="pre">0x80</span></tt> is encoded with the <tt class="docutils literal"><span class="pre">'latin-1'</span></tt>, <tt class="docutils literal"><span class="pre">'iso_8859_1'</span></tt> or
+<tt class="docutils literal"><span class="pre">'8859'</span></tt> character sets (which incidentally are different names for the same
+thing) we get the result we expected:</p>
+<textarea name="code" class="python">
+>>> unicode('\x80', encoding='latin-1')
+u'\x80'
+</textarea><div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">The character encodings Python supports are listed at
+<a href="http://docs.python.org/lib/standard-encodings.html" class="reference">http://docs.python.org/lib/standard-encodings.html</a></p>
+</div>
+<p>Unicode objects in Python have most of the same methods that normal Python
+strings provide. Python will try to use the <tt class="docutils literal"><span class="pre">'ascii'</span></tt> codec to convert
+strings to Unicode if you do an operation on both types:</p>
+<textarea name="code" class="python">
+>>> a = 'hello'
+>>> b = unicode(' world!')
+>>> print a + b
+u'hello world!'
+</textarea><p>You can encode a Unicode string using a particular encoding like this:</p>
+<textarea name="code" class="python">
+>>> u'Hello World!'.encode('UTF-8')
+'Hello World!'
+</textarea></div>
+<div class="section">
+<h2><a href="#id4" id="unicode-literals-in-python-source-code" name="unicode-literals-in-python-source-code" class="toc-backref">1.3   Unicode Literals in Python Source Code</a></h2>
+<p>In Python source code, Unicode literals are written as strings prefixed with
+the 'u' or 'U' character:</p>
+<textarea name="code" class="python">
+>>> u'abcdefghijk'
+>>> U'lmnopqrstuv'
+</textarea><p>You can also use <tt class="docutils literal"><span class="pre">"</span></tt>, <tt class="docutils literal"><span class="pre">"""`</span></tt> or <tt class="docutils literal"><span class="pre">'''</span></tt> versions too. For example:</p>
+<textarea name="code" class="python">
+>>> u"""This
+... is a really long
+... Unicode string"""
+</textarea><p>Specific code points can be written using the <tt class="docutils literal"><span class="pre">\u</span></tt> escape sequence, which is
+followed by four hex digits giving the code point. If you use <tt class="docutils literal"><span class="pre">\U</span></tt> instead
+you specify 8 hex digits instead of 4. Unicode literals can also use the same
+escape sequences as 8-bit strings, including <tt class="docutils literal"><span class="pre">\x</span></tt>, but <tt class="docutils literal"><span class="pre">\x</span></tt> only takes two
+hex digits so it can't express all the available code points. You can add
+characters to Unicode strings using the <tt class="docutils literal"><span class="pre">unichr()</span></tt> built-in function and find
+out what the ordinal is with <tt class="docutils literal"><span class="pre">ord()</span></tt>.</p>
+<p>Here is an example demonstrating the different alternatives:</p>
+<textarea name="code" class="python">
+>>> s = u"\x66\u0072\u0061\U0000006e" + unichr(231) + u"ais"
+>>> #     ^^^^ two-digit hex escape
+>>> #         ^^^^^^ four-digit Unicode escape
+>>> #                     ^^^^^^^^^^ eight-digit Unicode escape
+>>> for c in s:  print ord(c),
+...
+97 102 114 97 110 231 97 105 115
+>>> print s
+franÁais
+</textarea><p>Using escape sequences for code points greater than 127 is fine in small doses
+but Python 2.4 and above support writing Unicode literals in any encoding as
+long as you declare the encoding being used by including a special comment as
+either the first or second line of the source file:</p>
+<textarea name="code" class="python">
+#!/usr/bin/env python
+# -*- coding: latin-1 -*-
+
+u = u'abcdÈ'
+print ord(u[-1])
+</textarea><p>If you don't include such a comment, the default encoding used will be ASCII.
+Versions of Python before 2.4 were Euro-centric and assumed Latin-1 as a
+default encoding for string literals; in Python 2.4, characters greater than
+127 still work but result in a warning. For example, the following program has
+no encoding declaration:</p>
+<textarea name="code" class="python">
+#!/usr/bin/env python
+u = u'abcdÈ'
+print ord(u[-1])
+</textarea><p>When you run it with Python 2.4, it will output the following warning:</p>
+<pre class="literal-block">
+sys:1: DeprecationWarning: Non-ASCII character '\xe9' in file testas.py on line
+2, but no encoding declared; see http://www.python.org/peps/pep-0263.html for de
+tails
+</pre>
+<p>and then the following output:</p>
+<pre class="literal-block">
+233
+</pre>
+<p>For real world use it is recommended that you use the UTF-8 encoding for your
+file but you must be sure that your text editor actually saves the file as
+UTF-8 otherwise the Python interpreter will try to parse UTF-8 characters but
+they will actually be stored as something else.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Windows users who use the <a href="http://www.scintilla.org/SciTE.html" class="reference">SciTE</a>
+editor can specify the encoding of their file from the menu using the
+<tt class="docutils literal"><span class="pre">File->Encoding</span></tt>.</p>
+</div>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">If you are working with Unicode in detail you might also be interested in
+the <tt class="docutils literal"><span class="pre">unicodedata</span></tt> module which can be used to find out Unicode properties
+such as a character's name, category, numeric value and the like.</p>
+</div>
+</div>
+<div class="section">
+<h2><a href="#id5" id="input-and-output" name="input-and-output" class="toc-backref">1.4   Input and Output</a></h2>
+<p>We now know how to use Unicode in Python source code but input and output can
+also be different using Unicode. Of course, some libraries natively support
+Unicode and if these libraries return Unicode objects you will not have to do
+anything special to support them. XML parsers and SQL databases frequently
+support Unicode for example.</p>
+<p>If you remember from the discussion earlier, Unicode data consists of code
+points. In order to send Unicode data via a socket or write it to a file you
+usually need to encode it to a series of bytes and then decode the data back to
+Unicode when reading it. You can of course perform the encoding manually
+reading a byte at the time but since encodings such as UTF-8 can have variable
+numbers of bytes per character it is usually much easier to use Python's
+built-in support in the form of the <tt class="docutils literal"><span class="pre">codecs</span></tt> module.</p>
+<p>The codecs module includes a version of the <tt class="docutils literal"><span class="pre">open()</span></tt> function that
+returns a file-like object that assumes the file's contents are in a specified
+encoding and accepts Unicode parameters for methods such as <tt class="docutils literal"><span class="pre">.read()</span></tt> and
+<tt class="docutils literal"><span class="pre">.write()</span></tt>.</p>
+<p>The function's parameters are open(filename, mode='rb', encoding=None,
+errors='strict', buffering=1). <tt class="docutils literal"><span class="pre">mode</span></tt> can be 'r', 'w', or 'a', just like the
+corresponding parameter to the regular built-in <tt class="docutils literal"><span class="pre">open()</span></tt> function. You can
+add a <tt class="docutils literal"><span class="pre">+</span></tt> character to update the file. <tt class="docutils literal"><span class="pre">buffering</span></tt> is similar to the
+standard function's parameter. <tt class="docutils literal"><span class="pre">encoding</span></tt> is a string giving the encoding to
+use, if not specified or specified as <tt class="docutils literal"><span class="pre">None</span></tt>, a regular Python file object
+that accepts 8-bit strings is returned.  Otherwise, a wrapper object is
+returned, and data written to or read from the wrapper object will be converted
+as needed. <tt class="docutils literal"><span class="pre">errors</span></tt> specifies the action for encoding errors and can be one
+of the usual values of <tt class="docutils literal"><span class="pre">'strict'</span></tt>, <tt class="docutils literal"><span class="pre">'ignore'</span></tt>, or <tt class="docutils literal"><span class="pre">'replace'</span></tt> which we
+saw right at the begining of this document when we were encoding strings in
+Python source files.</p>
+<p>Here is an example of how to read Unicode from a UTF-8 encoded file:</p>
+<textarea name="code" class="python">
+import codecs
+f = codecs.open('unicode.txt', encoding='utf-8')
+for line in f:
+    print repr(line)
+</textarea><p>It's also possible to open files in update mode, allowing both reading and writing:</p>
+<textarea name="code" class="python">
+f = codecs.open('unicode.txt', encoding='utf-8', mode='w+')
+f.write(u"\x66\u0072\u0061\U0000006e" + unichr(231) + u"ais")
+f.seek(0)
+print repr(f.readline()[:1])
+f.close()
+</textarea><p>Notice that we used the <tt class="docutils literal"><span class="pre">repr()</span></tt> function to display the Unicode data. This
+is very useful because if you tried to print the Unicode data directly, Python
+would need to encode it before it could be sent the console and depending on
+which characters were present and the character set used by the console, an
+error might be raised. This is avoided if you use <tt class="docutils literal"><span class="pre">repr()</span></tt>.</p>
+<p>The Unicode character <tt class="docutils literal"><span class="pre">U+FEFF</span></tt> is used as a byte-order mark or BOM, and is often
+written as the first character of a file in order to assist with auto-detection
+of the file's byte ordering. Some encodings, such as UTF-16, expect a BOM to be
+present at the start of a file, but with others such as UTF-8 it isn't necessary.</p>
+<p>When such an encoding is used, the BOM will be automatically written as the
+first character and will be silently dropped when the file is read. There are
+variants of these encodings, such as 'utf-16-le' and 'utf-16-be' for
+little-endian and big-endian encodings, that specify one particular byte
+ordering and don't skip the BOM.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Some editors including SciTE will put a byte order mark (BOM) in the text
+file when saved as UTF-8, which is strange because UTF-8 doesn't need BOMs.</p>
+</div>
+</div>
+<div class="section">
+<h2><a href="#id6" id="unicode-filenames" name="unicode-filenames" class="toc-backref">1.5   Unicode Filenames</a></h2>
+<p>Most modern operating systems support the use of Unicode filenames. The
+filenames are transparently converted to the underlying filesystem encoding.
+The type of encoding depends on the operating system.</p>
+<p>On Windows 9x, the encoding is <tt class="docutils literal"><span class="pre">mbcs</span></tt>.</p>
+<p>On Mac OS X, the encoding is <tt class="docutils literal"><span class="pre">utf-8</span></tt>.</p>
+<p>On Unix, the encoding is the user's preference according to the
+result of nl_langinfo(CODESET), or None if the nl_langinfo(CODESET) failed.</p>
+<p>On Windows NT+, file names are Unicode natively, so no conversion is performed.
+getfilesystemencoding still returns <tt class="docutils literal"><span class="pre">mbcs</span></tt>, as this is the encoding that
+applications should use when they explicitly want to convert Unicode strings to
+byte strings that are equivalent when used as file names.</p>
+<p><tt class="docutils literal"><span class="pre">mbcs</span></tt> is a special encoding for Windows that effectively means "use
+whichever encoding is appropriate". In Python 2.3 and above you can find out
+the system encoding with <tt class="docutils literal"><span class="pre">sys.getfilesystemencoding()</span></tt>.</p>
+<p>Most file and directory functions and methods support Unicode. For example:</p>
+<textarea name="code" class="python">
+filename = u"\x66\u0072\u0061\U0000006e" + unichr(231) + u"ais"
+f = open(filename, 'w')
+f.write('Some data\n')
+f.close()
+</textarea><p>Other functions such as <tt class="docutils literal"><span class="pre">os.listdir()</span></tt> will return Unicode if you pass a
+Unicode argument and will try to return strings if you pass an ordinary 8 bit
+string. For example running this example as <tt class="docutils literal"><span class="pre">test.py</span></tt>:</p>
+<textarea name="code" class="python">
+filename = u"Sample " + unichar(5000)
+f = open(filename, 'w')
+f.close()
+
+import os
+print os.listdir('.')
+print os.listdir(u'.')
+</textarea><p>will produce the following output:</p>
+<blockquote>
+['Sample?', 'test.py']
+[u'Sampleu1388', u'test.py']</blockquote>
+</div>
+</div>
+<div class="section">
+<h1><a href="#id7" id="applying-this-to-web-programming" name="applying-this-to-web-programming" class="toc-backref">2   Applying this to Web Programming</a></h1>
+<p>So far we've seen how to use encoding in source files and seen how to decode
+text to Unicode and encode it back to text. We've also seen that Unicode
+objects can be manipulated in similar ways to strings and we've seen how to
+perform input and output operations on files. Next we are going to look at how
+best to use Unicode in a web app.</p>
+<p>The main rule is this:</p>
+<pre class="literal-block">
+Your application should use Unicode for all strings internally, decoding
+any input to Unicode as soon as it enters the application and encoding the
+Unicode to UTF-8 or another encoding only on output.
+</pre>
+<p>If you fail to do this you will find that <tt class="docutils literal"><span class="pre">UnicodeDecodeError</span></tt> s will start
+popping up in unexpected places when Unicode strings are used with normal 8-bit
+strings because Python's default encoding is ASCII and it will try to decode
+the text to ASCII and fail. It is always better to do any encoding or decoding
+at the edges of your application otherwise you will end up patching lots of
+different parts of your application unnecessarily as and when errors pop up.</p>
+<p>Unless you have a very good reason not to it is wise to use UTF-8 as the
+default encoding since it is so widely supported.</p>
+<p>The second rule is:</p>
+<pre class="literal-block">
+Always test your application with characters above 127 and above 255
+wherever possible.
+</pre>
+<p>If you fail to do this you might think your application is working fine, but as
+soon as your users do put in non-ASCII characters you will have problems.
+Using arabic is always a good test and www.google.ae is a good source of sample
+text.</p>
+<p>The third rule is:</p>
+<pre class="literal-block">
+Always do any checking of a string for illegal characters once it's in the
+form that will be used or stored, otherwise the illegal characters might be
+disguised.
+</pre>
+<p>For example, let's say you have a content management system that takes a
+Unicode filename, and you want to disallow paths with a '/' character. You
+might write this code:</p>
+<textarea name="code" class="python">
+def read_file(filename, encoding):
+    if '/' in filename:
+        raise ValueError("'/' not allowed in filenames")
+    unicode_name = filename.decode(encoding)
+    f = open(unicode_name, 'r')
+    # ... return contents of file ...
+</textarea><p>This is INCORRECT. If an attacker could specify the 'base64' encoding, they
+could pass <tt class="docutils literal"><span class="pre">L2V0Yy9wYXNzd2Q=</span></tt> which is the base-64 encoded form of the string
+<tt class="docutils literal"><span class="pre">'/etc/passwd'</span></tt> which is a file you clearly don't want an attacker to get
+hold of.  The above code looks for <tt class="docutils literal"><span class="pre">/</span></tt> characters in the encoded form and
+misses the dangerous character in the resulting decoded form.</p>
+<p>Those are the three basic rules so now we will look at some of the places you
+might want to perform Unicode decoding in a Pylons application.</p>
+<div class="section">
+<h2><a href="#id8" id="request-parameters" name="request-parameters" class="toc-backref">2.1   Request Parameters</a></h2>
+<p>Currently the Pylons input values come from <tt class="docutils literal"><span class="pre">request.params</span></tt> but these are
+not decoded to Unicode by default because not all input should be assumed to be
+Unicode data.</p>
+<p>If you would like However you can use the two functions below:</p>
+<textarea name="code" class="python">
+def decode_multi_dict(md, encoding="UTF-8", errors="strict"):
+    """Given a MultiDict, decode all its parts from the given encoding.
+
+    This modifies the MultiDict in place.
+
+    encoding, strict
+      These are passed to the decode function.
+
+    """
+    items = md.items()
+    md.clear()
+    for (k, v) in items:
+        md.add(k.decode(encoding, errors),
+               v.decode(encoding, errors))
+
+
+def decode_request(request, encoding="UTF-8", errors="strict"):
+    """Given a request object, decode GET and POST in place.
+
+    This implicitly takes care of params as well.
+
+    """
+    decode_multi_dict(request.GET, encoding, errors)
+    decode_multi_dict(request.POST, encoding, errors)
+</textarea><p>These can then be used as follows:</p>
+<textarea name="code" class="python">
+unicode_params = decode_request(request.params)
+</textarea><p>This code is discussed in <a href="http://pylonshq.com/project/pylonshq/ticket/135" class="reference">ticket 135</a> but shouldn't be used with
+file uploads since these shouldn't ordinarily be decoded to Unicode.</p>
+</div>
+<div class="section">
+<h2><a href="#id9" id="templating" name="templating" class="toc-backref">2.2   Templating</a></h2>
+<p>Pylons uses Myghty as its default templating language and Myghty 1.1 and above
+fully support Unicode. The Myghty documentation explains how to use Unicode and
+you at <a href="http://www.myghty.org/docs/unicode.myt" class="reference">http://www.myghty.org/docs/unicode.myt</a> but the important idea is that
+you can Unicode literals pretty much anywhere you can use normal 8-bit strings
+including in <tt class="docutils literal"><span class="pre">m.write()</span></tt> and <tt class="docutils literal"><span class="pre">m.comp()</span></tt>. You can also pass Unicode data to
+Pylons' <tt class="docutils literal"><span class="pre">render_response()</span></tt> and <tt class="docutils literal"><span class="pre">Response()</span></tt> callables.</p>
+<p>Any Unicode data output by Myghty is automatically decoded to whichever
+encoding you have chosen. The default is UTF-8 but you can choose which
+encoding to use by editing your project's <tt class="docutils literal"><span class="pre">config/environment.py</span></tt> file and
+adding an option like this:</p>
+<textarea name="code" class="python">
+# Add your own Myghty config options here, note that all config options will override
+# any Pylons config options
+
+myghty['output_encoding'] = 'UTF-8'
+</textarea><p>replacing <tt class="docutils literal"><span class="pre">UTF-8</span></tt> with the encoding you wish to use.</p>
+<p>If you need to disable Unicode support altogether you can set this:</p>
+<textarea name="code" class="python">
+myghty['disable_unicode'] = True
+</textarea><p>but again, you would have to have a good reason to want to do this.</p>
+</div>
+<div class="section">
+<h2><a href="#id10" id="output-encoding" name="output-encoding" class="toc-backref">2.3   Output Encoding</a></h2>
+<p>Web pages should be generated with a specific encoding, most likely UTF-8. At
+the very least, that means you should specify the following in the <tt class="docutils literal"><span class="pre"><head></span></tt>
+section:</p>
+<pre class="literal-block">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+</pre>
+<p>You should also set the charset in the <tt class="docutils literal"><span class="pre">Content-Type</span></tt> header:</p>
+<textarea name="code" class="python">
+respones = Response(...)
+response.headers['Content-type'] = 'text/html; charset=utf-8'
+</textarea><p>If you specify that your output is UTF-8, generally the web browser will
+give you UTF-8. If you want the browser to submit data using a different
+character set, you can set the encoding by adding the <tt class="docutils literal"><span class="pre">accept-encoding</span></tt>
+tag to your form. Here is an example:</p>
+<pre class="literal-block">
+<form accept-encoding="US-ASCII" ...>
+</pre>
+<p>However, be forewarned that if the user tries to give you non-ASCII
+text, then:</p>
+<blockquote>
+<ul class="simple">
+<li>Firefox will translate the non-ASCII text into HTML entities.</li>
+<li>IE will ignore your suggested encoding and give you UTF-8 anyway.</li>
+</ul>
+</blockquote>
+<p>The lesson to be learned is that if you output UTF-8, you had better be
+prepared to accept UTF-8 by decoding the data in <tt class="docutils literal"><span class="pre">request.params</span></tt> as
+described in the section above entitled "Request Parameters".</p>
+<p>Another technique which is sometimes used to determine the character set is to
+use an algorithm to analyse the input and guess the encoding based on
+probabilities.</p>
+<p>For instance, if you get a file, and you don't know what encoding it is encoded
+in, you can often rename the file with a .txt extension and then try to open it
+in Firefox.  Then you can use the "View->Character Encoding" menu to try to
+auto-detect the encoding.</p>
+</div>
+<div class="section">
+<h2><a href="#id11" id="databases" name="databases" class="toc-backref">2.4   Databases</a></h2>
+<p>Your database driver should automatically convert from Unicode objects to a
+particular charset when writing and back again when reading. Again it is normal
+to use UTF-8 which is well supported.</p>
+<p>You should check your database's documentation for information on how it handles
+Unicode.</p>
+<p>For example MySQL's Unicode documentation is here
+<a href="http://dev.mysql.com/doc/refman/5.0/en/charset-unicode.html" class="reference">http://dev.mysql.com/doc/refman/5.0/en/charset-unicode.html</a></p>
+<p>Also note that you need to consider both the encoding of the database
+and the encoding used by the database driver.</p>
+<p>If you're using MySQL together with SQLAlchemy, see the following, as
+there are some bugs in MySQLdb that you'll need to work around:</p>
+<p><a href="http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg00366.html" class="reference">http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg00366.html</a></p>
+</div>
+</div>
+<div class="section">
+<h1><a href="#id12" id="internationalization-and-localization" name="internationalization-and-localization" class="toc-backref">3   Internationalization and Localization</a></h1>
+<p>By now you should have a good idea of what Unicode is, how to use it in Python
+and which areas of you application need to pay specific attention to decoding and
+encoding Unicode data.</p>
+<p>This final section will look at the issue of making your application work with
+multiple languages.</p>
+<div class="section">
+<h2><a href="#id13" id="getting-started" name="getting-started" class="toc-backref">3.1   Getting Started</a></h2>
+<p>Everywhere in your code where you want strings to be available in different
+languages you wrap them in the <tt class="docutils literal"><span class="pre">_()</span></tt> function. There
+are also a number of other translation functions which are documented in the API reference at
+<a href="http://pylonshq.com/docs/module-pylons.i18n.translation.html" class="reference">http://pylonshq.com/docs/module-pylons.i18n.translation.html</a></p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">The <tt class="docutils literal"><span class="pre">_()</span></tt> function is a reference to the <tt class="docutils literal"><span class="pre">ugettext()</span></tt> function.
+<tt class="docutils literal"><span class="pre">_()</span></tt> is a convention for marking text to be translated and saves on keystrokes.
+<tt class="docutils literal"><span class="pre">ugettext()</span></tt> is the Unicode version of <tt class="docutils literal"><span class="pre">gettext()</span></tt>.</p>
+</div>
+<p>In our example we want the string <tt class="docutils literal"><span class="pre">'Hello'</span></tt> to appear in three different
+languages: English, French and Spanish. We also want to display the word
+<tt class="docutils literal"><span class="pre">'Hello'</span></tt> in the default language. We'll then go on to use some pural words
+too.</p>
+<p>Lets call our project <tt class="docutils literal"><span class="pre">translate_demo</span></tt>:</p>
+<pre class="literal-block">
+paster create --template=pylons translate_demo
+</pre>
+<p>Now lets add a friendly controller that says hello:</p>
+<pre class="literal-block">
+cd translate_demo
+paster controller hello
+</pre>
+<p>Edit <tt class="docutils literal"><span class="pre">controllers/hello.py</span></tt> controller to look like this making use of the
+<tt class="docutils literal"><span class="pre">_()</span></tt> function everywhere where the string <tt class="docutils literal"><span class="pre">Hello</span></tt> appears:</p>
+<textarea name="code" class="python">
+from translate_demo.lib.base import *
+
+class HelloController(BaseController):
+
+    def index(self):
+        resp = Response()
+        resp.write('Default: %s<br />' % _('Hello'))
+        for lang in ['fr','en','es']:
+            h.set_lang(lang)
+            resp.write("%s: %s<br />" % (h.get_lang(), _('Hello')))
+        return resp
+</textarea><p>When writing your controllers it is important not to piece sentences together manually because
+certain languages might need to invert the grammars. As an example this is bad:</p>
+<textarea name="code" class="python">
+# BAD!
+msg = _("He told her ")
+msg += _("not to go outside.")
+</textarea><p>but this is perfectly acceptable:</p>
+<textarea name="code" class="python">
+# GOOD
+msg = _("He told her not to go outside")
+</textarea><p>The controller has now been internationalized but it will raise a <tt class="docutils literal"><span class="pre">LanguageError</span></tt>
+until we have specified the alternative languages.</p>
+<p>Pylons uses <a href="http://www.gnu.org/software/gettext/" class="reference">GNU gettext</a> to handle
+internationalization. GNU gettext use three types of files in the
+translation framework.</p>
+<p>POT (Portable Object Template) files</p>
+<blockquote>
+The first step in the localization process. A program is used to search through
+your project's source code and pick out every string passed to one of the
+translation functions, such as <tt class="docutils literal"><span class="pre">_()</span></tt>. This list is put together in a
+specially-formatted template file that will form the basis of all
+translations. This is the <tt class="docutils literal"><span class="pre">.pot</span></tt> file.</blockquote>
+<p>PO (Portable Object) files</p>
+<blockquote>
+The second step in the localization process. Using the POT file as a template,
+the list of messages are translated and saved as a <tt class="docutils literal"><span class="pre">.po</span></tt> file.</blockquote>
+<p>MO (Machine Object) files</p>
+<blockquote>
+The final step in the localization process. The PO file is run through a
+program that turns it into an optimized machine-readable binary file, which is
+the <tt class="docutils literal"><span class="pre">.mo</span></tt> file. Compiling the translations to machine code makes the
+localized program much faster in retrieving the translations while it is
+running.</blockquote>
+<p>Versions of Pylons prior to 0.9.4 came with a setuptools extension to help with
+the extraction of strings and production of a <tt class="docutils literal"><span class="pre">.mo</span></tt> file. The implementation
+did not support Unicode nor the ungettext function and was therfore dropped in
+Python 0.9.4.</p>
+<p>You will therefore need to use an external program to perform these tasks.  You
+may use whichever you prefer but <tt class="docutils literal"><span class="pre">xgettext</span></tt> is highly recommended. Python's
+gettext utility has some bugs, especially regarding plurals.</p>
+<p>Here are some compatible tools and projects:</p>
+<p>The Rosetta Project (<a href="https://launchpad.ubuntu.com/rosetta/" class="reference">https://launchpad.ubuntu.com/rosetta/</a>)</p>
+<blockquote>
+The Ubuntu Linux project has a web site that allows you to translate
+messages without even looking at a PO or POT file, and export directly to a MO.</blockquote>
+<p>poEdit (<a href="http://www.poedit.org/" class="reference">http://www.poedit.org/</a>)</p>
+<blockquote>
+An open source program for Windows and UNIX/Linux which provides an easy-to-use
+GUI for editing PO files and generating MO files.</blockquote>
+<p>KBabel (<a href="http://i18n.kde.org/tools/kbabel/" class="reference">http://i18n.kde.org/tools/kbabel/</a>)</p>
+<blockquote>
+Another open source PO editing program for KDE.</blockquote>
+<p>GNU Gettext (<a href="http://www.gnu.org/software/gettext/" class="reference">http://www.gnu.org/software/gettext/</a>)</p>
+<blockquote>
+The official Gettext tools package contains command-line tools for creating
+POTs, manipulating POs, and generating MOs. For those comfortable with a
+command shell.</blockquote>
+<p>As an example we will quickly discuss the use of poEdit which is cross platform
+and has a GUI which makes it easier to get started with.</p>
+<p>To use poEdit with the <tt class="docutils literal"><span class="pre">translate_demo</span></tt> you would do the following:</p>
+<ol class="arabic simple">
+<li>Download and install poEdit.</li>
+<li>A dialog pops up. Fill in <em>all</em> the fields you can on the <tt class="docutils literal"><span class="pre">Project</span> <span class="pre">Info</span></tt> tab, enter the path to your project on the <tt class="docutils literal"><span class="pre">Paths</span></tt> tab (ie <tt class="docutils literal"><span class="pre">/path/to/translate_demo</span></tt>) and enter the following keywords on separate lines on the <tt class="docutils literal"><span class="pre">keywords</span></tt> tab: <tt class="docutils literal"><span class="pre">_</span></tt>, <tt class="docutils literal"><span class="pre">N_</span></tt>, <tt class="docutils literal"><span class="pre">ugettext</span></tt>, <tt class="docutils literal"><span class="pre">gettext</span></tt>, <tt class="docutils literal"><span class="pre">ngettext</span></tt>, <tt class="docutils literal"><span class="pre">ungettext</span></tt>.</li>
+<li>Click OK</li>
+</ol>
+<p>poEdit will search your source tree and find all the strings you have marked
+up. You can then enter your translations in whatever charset you chose in
+the project info tab. UTF-8 is a good choice.</p>
+<p>Finally, after entering your translations you then save the catalog and rename
+the <tt class="docutils literal"><span class="pre">.mo</span></tt> file produced to <tt class="docutils literal"><span class="pre">translate_demo.mo</span></tt> and put it in the
+<tt class="docutils literal"><span class="pre">translate_demo/i18n/es/LC_MESSAGES</span></tt> directory or whatever is appropriate for
+your translation.</p>
+<p>You will need to repeat the process of creating a <tt class="docutils literal"><span class="pre">.mo</span></tt> file for the <tt class="docutils literal"><span class="pre">fr</span></tt>,
+<tt class="docutils literal"><span class="pre">es</span></tt> and <tt class="docutils literal"><span class="pre">en</span></tt> translations.</p>
+<p>The relevant lines from <tt class="docutils literal"><span class="pre">i18n/en/LC_MESSAGES/translate_demo.po</span></tt> look like this:</p>
+<pre class="literal-block">
+#: translate_demo\controllers\hello.py:6 translate_demo\controllers\hello.py:9
+msgid "Hello"
+msgstr "Hello"
+</pre>
+<p>The relevant lines from <tt class="docutils literal"><span class="pre">i18n/es/LC_MESSAGES/translate_demo.po</span></tt> look like this:</p>
+<pre class="literal-block">
+#: translate_demo\controllers\hello.py:6 translate_demo\controllers\hello.py:9
+msgid "Hello"
+msgstr "°Hola!"
+</pre>
+<p>The relevant lines from <tt class="docutils literal"><span class="pre">i18n/fr/LC_MESSAGES/translate_demo.po</span></tt> look like this:</p>
+<pre class="literal-block">
+#: translate_demo\controllers\hello.py:6 translate_demo\controllers\hello.py:9
+msgid "Hello"
+msgstr "Bonjour"
+</pre>
+<p>Whichever tools you use you should end up with an <tt class="docutils literal"><span class="pre">i18n</span></tt> directory that looks
+like this when you have finished:</p>
+<pre class="literal-block">
+i18n/en/LC_MESSAGES/translate_demo.po
+i18n/en/LC_MESSAGES/translate_demo.mo
+i18n/es/LC_MESSAGES/translate_demo.po
+i18n/es/LC_MESSAGES/translate_demo.mo
+i18n/fr/LC_MESSAGES/translate_demo.po
+i18n/fr/LC_MESSAGES/translate_demo.mo
+</pre>
+</div>
+<div class="section">
+<h2><a href="#id14" id="testing-the-application" name="testing-the-application" class="toc-backref">3.2   Testing the Application</a></h2>
+<p>Start the server with the following command:</p>
+<pre class="literal-block">
+paster serve --reload development.ini
+</pre>
+<p>Test your controller by visiting <a href="http://localhost:5000/hello" class="reference">http://localhost:5000/hello</a>. You should see
+the following output:</p>
+<pre class="literal-block">
+Default: Hello
+fr: Bonjour
+en: Hello
+es: °Hola!
+</pre>
+<p>You can now set the language used in a controller on the fly.</p>
+<p>For example this could be used to allow a user to set which language they
+wanted your application to work in. You could save the value to the session
+object:</p>
+<textarea name="code" class="python">
+session['lang'] = 'en'
+</textarea><p>then on each controller call the language to be used could be read from the
+session and set in your controller's <tt class="docutils literal"><span class="pre">__before__()</span></tt> method so that the pages
+remained in the same language that was previously set:</p>
+<textarea name="code" class="python">
+def __before__(self, action):
+    if session.has_key('lang'):
+        h.set_lang(session['lang'])
+</textarea><p>One more useful thing to be able to do is to set the default language to be
+used in the configuration file. Just add a <tt class="docutils literal"><span class="pre">lang</span></tt> variable together with the
+code of the language you wanted to use in your <tt class="docutils literal"><span class="pre">development.ini</span></tt> file. For
+example to set the default language to Spanish you would add <tt class="docutils literal"><span class="pre">lang</span> <span class="pre">=</span> <span class="pre">es</span></tt> to
+your <tt class="docutils literal"><span class="pre">development.ini</span></tt>. The relevant part from the file might look something
+like this:</p>
+<textarea name="code" class="pasteini">
+[app:main]
+use = egg:translate_demo
+lang = es
+</textarea><p>If you are running the server with the <tt class="docutils literal"><span class="pre">--reload</span></tt> option the server will
+automatically restart if you change the <tt class="docutils literal"><span class="pre">development.ini</span></tt> file. Otherwise
+restart the server manually and the output would this time be as follows:</p>
+<pre class="literal-block">
+Default: °Hola!
+fr: Bonjour
+en: Hello
+es: °Hola!
+</pre>
+</div>
+<div class="section">
+<h2><a href="#id15" id="missing-translations" name="missing-translations" class="toc-backref">3.3   Missing Translations</a></h2>
+<p>If your code calls <tt class="docutils literal"><span class="pre">_()</span></tt> with a string that doesn't exist in your language
+catalogue, the string passed to <tt class="docutils literal"><span class="pre">_()</span></tt> is returned instead.</p>
+<p>Modify the last line of the hello controller to look like this:</p>
+<textarea name="code" class="python">
+resp.write("%s: %s %s<br />" % (h.get_lang(), _('Hello'), _('World!')))
+</textarea><div class="warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">Of course, in real life breaking up sentences in this way is very dangerous because some
+grammars might require the order of the words to be different.</p>
+</div>
+<p>If you run the example again the output will be:</p>
+<pre class="literal-block">
+Default: °Hola!
+fr: Bonjour World!
+en: Hello World!
+es: °Hola! World!
+</pre>
+<p>This is because we never provided a translation for the string <tt class="docutils literal"><span class="pre">'World!'</span></tt> so
+the string itself is used.</p>
+</div>
+<div class="section">
+<h2><a href="#id16" id="translations-within-templates" name="translations-within-templates" class="toc-backref">3.4   Translations Within Templates</a></h2>
+<p>You can also use the <tt class="docutils literal"><span class="pre">_()</span></tt> function within templates in exactly the same way
+you do in code. For example:</p>
+<textarea name="code" class="html">
+<% _('Hello') %>
+</textarea><p>would produce the string <tt class="docutils literal"><span class="pre">'Hello'</span></tt> in the language you had set.</p>
+<p>There is one complication though. gettext's <tt class="docutils literal"><span class="pre">xgettext</span></tt> command can only extract
+strings that need translating from Python code in <tt class="docutils literal"><span class="pre">.py</span></tt> files. This means
+that if you write <tt class="docutils literal"><span class="pre">_('Hello')</span></tt> in a template such as a Myghty template,
+<tt class="docutils literal"><span class="pre">xgettext</span></tt> will not find the string <tt class="docutils literal"><span class="pre">'Hello'</span></tt> as one which needs
+translating.</p>
+<p>As long as <tt class="docutils literal"><span class="pre">xgettext</span></tt> can find a string marked for translation with one
+of the translation functions and defined in Python code in your project
+filesystem it will manage the translation when the same string is defined in a
+Myghty template and marked for translation.</p>
+<p>One solution to ensure all strings are picked up for translation is to create a
+file in <tt class="docutils literal"><span class="pre">lib</span></tt> with an appropriate filename, <tt class="docutils literal"><span class="pre">i18n.py</span></tt> for example, and then
+add a list of all the strings which appear in your templates so that your
+translation tool can then extract the strings in <tt class="docutils literal"><span class="pre">lib/i18n.py</span></tt> for
+translation and use the translated versions in your templates as well.</p>
+<p>For example if you wanted to ensure the translated string <tt class="docutils literal"><span class="pre">'Good</span> <span class="pre">Morning'</span></tt>
+was available in all templates you could create a <tt class="docutils literal"><span class="pre">lib/i18n.py</span></tt> file that
+looked something like this:</p>
+<textarea name="code" class="python">
+from base import _
+_('Good Morning')
+</textarea><p>This approach requires quite a lot of work and is rather fragile. The best
+solution if you are using a templating system such as Myghty or Cheetah which
+uses compiled Python files is to use a Makefile to ensure that every template
+is compiled to Python before running the extraction tool to make sure that
+every template is scanned.</p>
+<p>Of course, if your cache directory is in the default location or elsewhere
+within your project's filesystem, you will probably find that all templates
+have been compiled as Python files during the course of the development process.
+This means that your tool's extraction command will successfully pick up
+strings to translate from the cached files anyway.</p>
+<p>You may also find that your extraction tool is capable of extracting the
+strings correctly from the template anyway, particularly if the templating
+langauge is quite similar to Python. It is best not to rely on this though.</p>
+</div>
+<div class="section">
+<h2><a href="#id17" id="producing-a-python-egg" name="producing-a-python-egg" class="toc-backref">3.5   Producing a Python Egg</a></h2>
+<p>Finally you can produce an egg of your project which includes the translation
+files like this:</p>
+<pre class="literal-block">
+python setup.py bdist_egg
+</pre>
+<p>The <tt class="docutils literal"><span class="pre">setup.py</span></tt> automatically includes the <tt class="docutils literal"><span class="pre">.mo</span></tt> language catalogs your
+application needs so that your application can be distributed as an egg. This
+is done with the following line in your <tt class="docutils literal"><span class="pre">setup.py</span></tt> file:</p>
+<pre class="literal-block">
+package_data={'translate_demo': ['i18n/*/LC_MESSAGES/*.mo']},
+</pre>
+<p>Internationalization support is zip safe so your application can be run
+directly from the egg without the need for <tt class="docutils literal"><span class="pre">easy_install</span></tt> to extract it.</p>
+</div>
+<div class="section">
+<h2><a href="#id18" id="plural-forms" name="plural-forms" class="toc-backref">3.6   Plural Forms</a></h2>
+<p>Pylons also defines <tt class="docutils literal"><span class="pre">ungettext()</span></tt> and <tt class="docutils literal"><span class="pre">ngettext()</span></tt> functions which can be imported
+from <tt class="docutils literal"><span class="pre">pylons.i18n</span></tt>. They are designed for internationalizing plural words and can be
+used as follows:</p>
+<textarea name="code" class="python">
+from pylons.i18n import ungettext
+
+ungettext(
+    'There is %(num)d file here',
+    'There are %(num)d files here',
+    n
+) % {'num': n}
+</textarea><p>If you wish to use plural forms in your application you need to add the appropriate
+headers to the <tt class="docutils literal"><span class="pre">.po</span></tt> files for the language you are using. You can read more about
+this at <a href="http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#SEC150" class="reference">http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#SEC150</a></p>
+<p>One thing to keep in mind is that other languages don't have the same
+plural forms as English.  While English only has 2 pulral forms, singular and
+plural, Slovenian has 4!  That means that you must use gettext's
+support for pluralization if you hope to get pluralization right.
+Specifically, the following will not work:</p>
+<textarea name="code" class="python">
+# BAD!
+    if n == 1:
+        msg = _("There was no dog.")
+    else:
+        msg = _("There were no dogs.")
+</textarea></div>
+</div>
+<div class="section">
+<h1><a href="#id19" id="summary" name="summary" class="toc-backref">4   Summary</a></h1>
+<p>Hopefully you now understand the history of Unicode, how to use it in Python
+and where to apply Unicode encoding and decoding in a Pylons application. You
+should also be able to use Unicode in your web app remembering the basic rule to
+use UTF-8 to talk to the world, do the encode and decode at the edge of your
+application.</p>
+<p>You should also be able to internationalize and then localize your application
+using Pylons' support for GNU gettext.</p>
+</div>
+<div class="section">
+<h1><a href="#id20" id="further-reading" name="further-reading" class="toc-backref">5   Further Reading</a></h1>
+<p>This information is based partly on the following articles which can be
+consulted for further information.:</p>
+<p><a href="http://www.joelonsoftware.com/articles/Unicode.html" class="reference">http://www.joelonsoftware.com/articles/Unicode.html</a></p>
+<p><a href="http://www.amk.ca/python/howto/unicode" class="reference">http://www.amk.ca/python/howto/unicode</a></p>
+<p><a href="http://en.wikipedia.org/wiki/Internationalization" class="reference">http://en.wikipedia.org/wiki/Internationalization</a></p>
+<p>Please feel free to report any mistakes to the Pylons mailing list or to the
+author. Any corrections or clarifications would be gratefully received.</p>
+</div>
+
+</div>
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/modtest.html b/lib3/mako-0.3.6/test/templates/modtest.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/modtest.html
@@ -0,0 +1,1 @@
+this is a test
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/read_unicode.html b/lib3/mako-0.3.6/test/templates/read_unicode.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/read_unicode.html
@@ -0,0 +1,10 @@
+<% 
+try:
+    file_content = open(path)
+except:
+    raise "Should never execute here"
+doc_content = ''.join(file_content.readlines())
+file_content.close()
+%>
+
+${unicode(doc_content, encoding='utf-8')}
diff --git a/lib3/mako-0.3.6/test/templates/read_unicode_py3k.html b/lib3/mako-0.3.6/test/templates/read_unicode_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/read_unicode_py3k.html
@@ -0,0 +1,10 @@
+<% 
+try:
+    file_content = open(path)
+except:
+    raise "Should never execute here"
+doc_content = ''.join(file_content.readlines())
+file_content.close()
+%>
+
+${bytes(doc_content, encoding='utf-8')}
diff --git a/lib3/mako-0.3.6/test/templates/runtimeerr.html b/lib3/mako-0.3.6/test/templates/runtimeerr.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/runtimeerr.html
@@ -0,0 +1,4 @@
+<%
+    print y
+    y = 10
+%>
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/runtimeerr_py3k.html b/lib3/mako-0.3.6/test/templates/runtimeerr_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/runtimeerr_py3k.html
@@ -0,0 +1,4 @@
+<%
+    print(y)
+    y = 10
+%>
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/subdir/foo/modtest.html.py b/lib3/mako-0.3.6/test/templates/subdir/foo/modtest.html.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/subdir/foo/modtest.html.py
@@ -0,0 +1,25 @@
+from mako import runtime, filters, cache
+UNDEFINED = runtime.UNDEFINED
+__M_dict_builtin = dict
+__M_locals_builtin = locals
+_magic_number = 5
+_modified_time = 1267565427.799504
+_template_filename='/Users/classic/dev/mako/test/templates/subdir/modtest.html'
+_template_uri='/subdir/modtest.html'
+_template_cache=cache.Cache(__name__, _modified_time)
+_source_encoding=None
+_exports = []
+
+
+def render_body(context,**pageargs):
+    context.caller_stack._push_frame()
+    try:
+        __M_locals = __M_dict_builtin(pageargs=pageargs)
+        __M_writer = context.writer()
+        # SOURCE LINE 1
+        __M_writer('this is a test')
+        return ''
+    finally:
+        context.caller_stack._pop_frame()
+
+
diff --git a/lib3/mako-0.3.6/test/templates/subdir/incl.html b/lib3/mako-0.3.6/test/templates/subdir/incl.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/subdir/incl.html
@@ -0,0 +1,2 @@
+
+    this is include 2
diff --git a/lib3/mako-0.3.6/test/templates/subdir/index.html b/lib3/mako-0.3.6/test/templates/subdir/index.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/subdir/index.html
@@ -0,0 +1,3 @@
+
+    this is sub index
+    <%include file="incl.html"/>
diff --git a/lib3/mako-0.3.6/test/templates/subdir/modtest.html b/lib3/mako-0.3.6/test/templates/subdir/modtest.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/subdir/modtest.html
@@ -0,0 +1,1 @@
+this is a test
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/unicode.html b/lib3/mako-0.3.6/test/templates/unicode.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/unicode.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/unicode_arguments.html b/lib3/mako-0.3.6/test/templates/unicode_arguments.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/unicode_arguments.html
@@ -0,0 +1,10 @@
+# coding: utf-8
+
+<%def name="my_def(x)">
+    x is: ${x}
+</%def>
+
+${my_def(u'drôle de petite voix m’a réveillé')}
+<%self:my_def x='drôle de petite voix m’a réveillé'/>
+<%self:my_def x="${u'drôle de petite voix m’a réveillé'}"/>
+<%call expr="my_def(u'drôle de petite voix m’a réveillé')"/>
diff --git a/lib3/mako-0.3.6/test/templates/unicode_arguments_py3k.html b/lib3/mako-0.3.6/test/templates/unicode_arguments_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/unicode_arguments_py3k.html
@@ -0,0 +1,10 @@
+# coding: utf-8
+
+<%def name="my_def(x)">
+    x is: ${x}
+</%def>
+
+${my_def('drôle de petite voix m’a réveillé')}
+<%self:my_def x='drôle de petite voix m’a réveillé'/>
+<%self:my_def x="${'drôle de petite voix m’a réveillé'}"/>
+<%call expr="my_def('drôle de petite voix m’a réveillé')"/>
diff --git a/lib3/mako-0.3.6/test/templates/unicode_code.html b/lib3/mako-0.3.6/test/templates/unicode_code.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/unicode_code.html
@@ -0,0 +1,7 @@
+## -*- coding: utf-8 -*-
+<%
+    x = u"drôle de petite voix m’a réveillé."
+%>
+% if x==u"drôle de petite voix m’a réveillé.":
+    hi, ${x}
+% endif
diff --git a/lib3/mako-0.3.6/test/templates/unicode_code_py3k.html b/lib3/mako-0.3.6/test/templates/unicode_code_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/unicode_code_py3k.html
@@ -0,0 +1,7 @@
+## -*- coding: utf-8 -*-
+<%
+    x = "drôle de petite voix m’a réveillé."
+%>
+% if x=="drôle de petite voix m’a réveillé.":
+    hi, ${x}
+% endif
diff --git a/lib3/mako-0.3.6/test/templates/unicode_expr.html b/lib3/mako-0.3.6/test/templates/unicode_expr.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/unicode_expr.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+${u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
diff --git a/lib3/mako-0.3.6/test/templates/unicode_expr_py3k.html b/lib3/mako-0.3.6/test/templates/unicode_expr_py3k.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/unicode_expr_py3k.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+${"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
diff --git a/lib3/mako-0.3.6/test/templates/unicode_runtime_error.html b/lib3/mako-0.3.6/test/templates/unicode_runtime_error.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/unicode_runtime_error.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+<% print 'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »' + int(5/0) %>
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/templates/unicode_syntax_error.html b/lib3/mako-0.3.6/test/templates/unicode_syntax_error.html
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/templates/unicode_syntax_error.html
@@ -0,0 +1,2 @@
+## -*- coding: utf-8 -*-
+<% print 'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! » %>
\ No newline at end of file
diff --git a/lib3/mako-0.3.6/test/test_ast.py b/lib3/mako-0.3.6/test/test_ast.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_ast.py
@@ -0,0 +1,273 @@
+import unittest
+
+from mako import ast, exceptions, pyparser, util
+from test import eq_
+
+exception_kwargs = {'source':'', 'lineno':0, 'pos':0, 'filename':''}
+
+class AstParseTest(unittest.TestCase):
+
+    def test_locate_identifiers(self):
+        """test the location of identifiers in a python code string"""
+        code = """
+a = 10
+b = 5
+c = x * 5 + a + b + q
+(g,h,i) = (1,2,3)
+[u,k,j] = [4,5,6]
+foo.hoho.lala.bar = 7 + gah.blah + u + blah
+for lar in (1,2,3):
+    gh = 5
+    x = 12
+("hello world, ", a, b)
+("Another expr", c)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.declared_identifiers == set(['a','b','c', 'g', 'h', 'i', 'u', 'k', 'j', 'gh', 'lar', 'x'])
+        assert parsed.undeclared_identifiers == set(['x', 'q', 'foo', 'gah', 'blah'])
+    
+        parsed = ast.PythonCode("x + 5 * (y-z)", **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['x', 'y', 'z'])
+        assert parsed.declared_identifiers == set()
+
+    def test_locate_identifiers_2(self):
+        code = """
+import foobar
+from lala import hoho, yaya
+import bleep as foo
+result = []
+data = get_data()
+for x in data:
+    result.append(x+7)
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['get_data'])
+        assert parsed.declared_identifiers == set(['result', 'data', 'x', 'hoho', 'foobar', 'foo', 'yaya'])
+
+    def test_locate_identifiers_3(self):
+        """test that combination assignment/expressions of the same identifier log the ident as 'undeclared'"""
+        code = """
+x = x + 5
+for y in range(1, y):
+    ("hi",)
+[z for z in range(1, z)]
+(q for q in range (1, q))
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['x', 'y', 'z', 'q', 'range'])
+    
+    def test_locate_identifiers_4(self):
+        if util.py3k:
+            code = """
+x = 5
+(y, )
+def mydef(mydefarg):
+    print("mda is", mydefarg)
+"""    
+        else:
+            code = """
+x = 5
+(y, )
+def mydef(mydefarg):
+    print "mda is", mydefarg
+"""    
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['y'])
+        assert parsed.declared_identifiers == set(['mydef', 'x'])
+    
+    def test_locate_identifiers_5(self):
+        if util.py3k:
+            code = """
+try:
+    print(x)
+except:
+    print(y)
+"""
+        else:
+            
+            code = """
+try:
+    print x
+except:
+    print y
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['x', 'y'])
+    
+    def test_locate_identifiers_6(self):
+        code = """
+def foo():
+    return bar()
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['bar'])
+        
+        if util.py3k:
+            code = """
+def lala(x, y):
+    return x, y, z
+print(x)
+"""
+        else:
+            code = """
+def lala(x, y):
+    return x, y, z
+print x
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['z', 'x'])
+        assert parsed.declared_identifiers == set(['lala'])
+        
+        if util.py3k:
+            code = """
+def lala(x, y):
+    def hoho():
+        def bar():
+            z = 7
+print(z)
+"""
+        else:
+            code = """
+def lala(x, y):
+    def hoho():
+        def bar():
+            z = 7
+print z
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['z'])
+        assert parsed.declared_identifiers == set(['lala'])
+    
+    def test_locate_identifiers_7(self):
+        code = """
+import foo.bar
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.declared_identifiers == set(['foo'])
+        assert parsed.undeclared_identifiers == set()
+
+    def test_locate_identifiers_8(self):
+        code = """
+class Hi(object):
+    foo = 7
+    def hoho(self):
+        x = 5
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.declared_identifiers == set(['Hi'])
+        assert parsed.undeclared_identifiers == set()
+    
+    def test_locate_identifiers_9(self):
+        code = """
+    ",".join([t for t in ("a", "b", "c")])
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.declared_identifiers == set(['t'])
+        assert parsed.undeclared_identifiers == set(['t'])
+        
+        code = """
+    [(val, name) for val, name in x]
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        assert parsed.declared_identifiers == set(['val', 'name'])
+        assert parsed.undeclared_identifiers == set(['val', 'name', 'x'])
+        
+    def test_locate_identifiers_10(self):
+        code = """
+lambda q: q + 5
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set())
+        eq_(parsed.undeclared_identifiers, set())
+        
+    def test_locate_identifiers_11(self):
+        code = """
+def x(q):
+    return q + 5
+"""
+        parsed = ast.PythonCode(code, **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['x']))
+        eq_(parsed.undeclared_identifiers, set())
+
+    def test_no_global_imports(self):
+        code = """
+from foo import *
+import x as bar
+"""
+        self.assertRaises(exceptions.CompileException, ast.PythonCode, code, **exception_kwargs)
+            
+    def test_python_fragment(self):
+        parsed = ast.PythonFragment("for x in foo:", **exception_kwargs)
+        assert parsed.declared_identifiers == set(['x'])
+        assert parsed.undeclared_identifiers == set(['foo'])
+        
+        parsed = ast.PythonFragment("try:", **exception_kwargs)
+
+        if util.py3k:
+            parsed = ast.PythonFragment("except MyException as e:", **exception_kwargs)
+        else:
+            parsed = ast.PythonFragment("except MyException, e:", **exception_kwargs)
+        eq_(parsed.declared_identifiers, set(['e']))
+        eq_(parsed.undeclared_identifiers, set(['MyException']))
+    
+    def test_argument_list(self):
+        parsed = ast.ArgumentList("3, 5, 'hi', x+5, context.get('lala')", **exception_kwargs)
+        assert parsed.undeclared_identifiers == set(['x', 'context'])
+        assert [x for x in parsed.args] == ["3", "5", "'hi'", "(x + 5)", "context.get('lala')"]
+
+        parsed = ast.ArgumentList("h", **exception_kwargs)
+        assert parsed.args == ["h"]
+
+    def test_function_decl(self):
+        """test getting the arguments from a function"""
+        code = "def foo(a, b, c=None, d='hi', e=x, f=y+7):pass"
+        parsed = ast.FunctionDecl(code, **exception_kwargs)
+        assert parsed.funcname=='foo'
+        assert parsed.argnames==['a', 'b', 'c', 'd', 'e', 'f']
+
+    def test_function_decl_2(self):
+        """test getting the arguments from a function"""
+        code = "def foo(a, b, c=None, *args, **kwargs):pass"
+        parsed = ast.FunctionDecl(code, **exception_kwargs)
+        assert parsed.funcname=='foo'
+        assert parsed.argnames==['a', 'b', 'c', 'args', 'kwargs']
+    
+    def test_expr_generate(self):
+        """test the round trip of expressions to AST back to python source"""
+        x = 1
+        y = 2
+        class F(object):
+            def bar(self, a,b):
+                return a + b
+        def lala(arg):
+            return "blah" + arg
+        local_dict = dict(x=x, y=y, foo=F(), lala=lala)
+        
+        code = "str((x+7*y) / foo.bar(5,6)) + lala('ho')"
+        astnode = pyparser.parse(code)
+        newcode = pyparser.ExpressionGenerator(astnode).value()
+        assert (eval(code, local_dict) == eval(newcode, local_dict))
+        
+        a = ["one", "two", "three"]
+        hoho = {'somevalue':"asdf"}
+        g = [1,2,3,4,5]
+        local_dict = dict(a=a,hoho=hoho,g=g)
+        code = "a[2] + hoho['somevalue'] + repr(g[3:5]) + repr(g[3:]) + repr(g[:5])"
+        astnode = pyparser.parse(code)
+        newcode = pyparser.ExpressionGenerator(astnode).value()
+        assert(eval(code, local_dict) == eval(newcode, local_dict))
+        
+        local_dict={'f':lambda :9, 'x':7}
+        code = "x+f()"
+        astnode = pyparser.parse(code)
+        newcode = pyparser.ExpressionGenerator(astnode).value()
+        assert(eval(code, local_dict)) == eval(newcode, local_dict)
+
+        for code in ["repr({'x':7,'y':18})", "repr([])", "repr({})", "repr([{3:[]}])", "repr({'x':37*2 + len([6,7,8])})", "repr([1, 2, {}, {'x':'7'}])", "repr({'x':-1})", "repr(((1,2,3), (4,5,6)))", "repr(1 and 2 and 3 and 4)", "repr(True and False or 55)", "repr(1 & 2 | 3)", "repr(3//5)", "repr(3^5)", "repr([q.endswith('e') for q in ['one', 'two', 'three']])", "repr([x for x in (5,6,7) if x == 6])", "repr(not False)"]:
+            local_dict={}
+            astnode = pyparser.parse(code)
+            newcode = pyparser.ExpressionGenerator(astnode).value()
+            assert(eval(code, local_dict)) == eval(newcode, local_dict), "%s != %s" % (code, newcode)
+
+    
+    
diff --git a/lib3/mako-0.3.6/test/test_babelplugin.py b/lib3/mako-0.3.6/test/test_babelplugin.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_babelplugin.py
@@ -0,0 +1,42 @@
+
+from test import TemplateTest, template_base, skip_if
+
+try:
+    import babel
+    from mako.ext.babelplugin import extract
+except:
+    babel = None
+    
+import os
+
+
+class ExtractMakoTestCase(TemplateTest):
+    @skip_if(lambda: not babel, 'babel not installed: skipping babelplugin test')
+    
+    def test_extract(self):
+        mako_tmpl = open(os.path.join(template_base, 'gettext.mako'))
+        messages = list(extract(mako_tmpl, {'_': None, 'gettext': None,
+                                            'ungettext': (1, 2)},
+                                ['TRANSLATOR:'], {}))
+        expected = \
+            [(1, '_', 'Page arg 1', []),
+             (1, '_', 'Page arg 2', []),
+             (10, 'gettext', 'Begin', []),
+             (14, '_', 'Hi there!', ['TRANSLATOR: Hi there!']),
+             (19, '_', 'Hello', []),
+             (22, '_', 'Welcome', []),
+             (25, '_', 'Yo', []),
+             (36, '_', 'The', ['TRANSLATOR: Ensure so and', 'so, thanks']),
+             (36, 'ungettext', ('bunny', 'bunnies', None), []),
+             (41, '_', 'Goodbye', ['TRANSLATOR: Good bye']),
+             (44, '_', 'Babel', []),
+             (45, 'ungettext', ('hella', 'hellas', None), []),
+             (62, '_', 'Goodbye, really!', ['TRANSLATOR: HTML comment']),
+             (65, '_', 'P.S. byebye', []),
+             (71, '_', 'Top', []), 
+             (77, '_', 'foo', []),
+             (77, '_', 'baz', []),
+             (79, '_', 'bar', [])
+             ]
+        self.assertEqual(expected, messages)
+
diff --git a/lib3/mako-0.3.6/test/test_cache.py b/lib3/mako-0.3.6/test/test_cache.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_cache.py
@@ -0,0 +1,404 @@
+from mako.template import Template
+from mako.lookup import TemplateLookup
+from mako import lookup
+import shutil, unittest, os
+from .util import result_lines
+from test import TemplateTest, template_base, module_base
+
+try:
+    import beaker
+except:
+    from nose import SkipTest
+    raise SkipTest("Beaker is required for these tests.")
+    
+class MockCache(object):
+    def __init__(self, realcache):
+        self.realcache = realcache
+    def get(self, key, **kwargs):
+        self.key = key
+        self.kwargs = kwargs.copy()
+        self.kwargs.pop('createfunc', None)
+        self.kwargs.pop('defname', None)
+        return self.realcache.get(key, **kwargs)
+    
+class CacheTest(TemplateTest):
+    def test_def(self):
+        t = Template("""
+        <%!
+            callcount = [0]
+        %>
+        <%def name="foo()" cached="True">
+            this is foo
+            <%
+            callcount[0] += 1
+            %>
+        </%def>
+    
+        ${foo()}
+        ${foo()}
+        ${foo()}
+        callcount: ${callcount}
+""")
+        m = self._install_mock_cache(t)
+        assert result_lines(t.render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        assert m.kwargs == {}
+
+    def test_cache_enable(self):
+        t = Template("""
+            <%!
+                callcount = [0]
+            %>
+            <%def name="foo()" cached="True">
+                <% callcount[0] += 1 %>
+            </%def>
+            ${foo()}
+            ${foo()}
+            callcount: ${callcount}
+        """, cache_enabled=False)
+        m = self._install_mock_cache(t)
+
+        assert t.render().strip() =="callcount: [2]"
+                
+    def test_nested_def(self):
+        t = Template("""
+        <%!
+            callcount = [0]
+        %>
+        <%def name="foo()">
+            <%def name="bar()" cached="True">
+                this is foo
+                <%
+                callcount[0] += 1
+                %>
+            </%def>
+            ${bar()}
+        </%def>
+
+        ${foo()}
+        ${foo()}
+        ${foo()}
+        callcount: ${callcount}
+""")
+        m = self._install_mock_cache(t)
+        assert result_lines(t.render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        assert m.kwargs == {}
+        
+    def test_page(self):
+        t = Template("""
+        <%!
+            callcount = [0]
+        %>
+        <%page cached="True"/>
+        this is foo
+        <%
+        callcount[0] += 1
+        %>
+        callcount: ${callcount}
+""")
+        m = self._install_mock_cache(t)
+        t.render()
+        t.render()
+        assert result_lines(t.render()) == [
+            "this is foo",
+            "callcount: [1]"
+        ]
+        assert m.kwargs == {}
+
+    def test_dynamic_key_with_funcargs(self):
+        t = Template("""
+            <%def name="foo(num=5)" cached="True" cache_key="foo_${str(num)}">
+             hi
+            </%def>
+
+            ${foo()}
+        """)
+        m = self._install_mock_cache(t)
+        t.render()
+        t.render()
+        assert result_lines(t.render()) == ['hi']
+        assert m.key == "foo_5"
+
+        t = Template("""
+            <%def name="foo(*args, **kwargs)" cached="True" cache_key="foo_${kwargs['bar']}">
+             hi
+            </%def>
+
+            ${foo(1, 2, bar='lala')}
+        """)
+        m = self._install_mock_cache(t)
+        t.render()
+        assert result_lines(t.render()) == ['hi']
+        assert m.key == "foo_lala"
+
+        t = Template('''
+        <%page args="bar='hi'" cache_key="foo_${bar}" cached="True"/>
+         hi
+        ''')
+        m = self._install_mock_cache(t)
+        t.render()
+        assert result_lines(t.render()) == ['hi']
+        assert m.key == "foo_hi"
+
+        
+    def test_dynamic_key_with_imports(self):
+        lookup = TemplateLookup()
+        lookup.put_string("foo.html", """
+        <%!
+            callcount = [0]
+        %>
+        <%namespace file="ns.html" import="*"/>
+        <%page cached="True" cache_key="${foo}"/>
+        this is foo
+        <%
+        callcount[0] += 1
+        %>
+        callcount: ${callcount}
+""")
+        lookup.put_string("ns.html", """""")
+        t = lookup.get_template("foo.html")
+        m = self._install_mock_cache(t)
+        t.render(foo='somekey')
+        t.render(foo='somekey')
+        assert result_lines(t.render(foo='somekey')) == [
+            "this is foo",
+            "callcount: [1]"
+        ]
+        assert m.kwargs == {}
+        
+    def test_fileargs_implicit(self):
+        l = lookup.TemplateLookup(module_directory=module_base)
+        l.put_string("test","""
+                <%!
+                    callcount = [0]
+                %>
+                <%def name="foo()" cached="True" cache_type='dbm'>
+                    this is foo
+                    <%
+                    callcount[0] += 1
+                    %>
+                </%def>
+
+                ${foo()}
+                ${foo()}
+                ${foo()}
+                callcount: ${callcount}
+        """)
+        
+        m = self._install_mock_cache(l.get_template('test'))
+        assert result_lines(l.get_template('test').render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        assert m.kwargs == {'type':'dbm', 'data_dir':module_base}
+        
+    def test_fileargs_deftag(self):
+        t = Template("""
+        <%%!
+            callcount = [0]
+        %%>
+        <%%def name="foo()" cached="True" cache_type='file' cache_dir='%s'>
+            this is foo
+            <%%
+            callcount[0] += 1
+            %%>
+        </%%def>
+
+        ${foo()}
+        ${foo()}
+        ${foo()}
+        callcount: ${callcount}
+""" % module_base)
+        m = self._install_mock_cache(t)
+        assert result_lines(t.render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        assert m.kwargs == {'type':'file','data_dir':module_base}
+
+    def test_fileargs_pagetag(self):
+        t = Template("""
+        <%%page cache_dir='%s' cache_type='dbm'/>
+        <%%!
+            callcount = [0]
+        %%>
+        <%%def name="foo()" cached="True">
+            this is foo
+            <%%
+            callcount[0] += 1
+            %%>
+        </%%def>
+
+        ${foo()}
+        ${foo()}
+        ${foo()}
+        callcount: ${callcount}
+""" % module_base)
+        m = self._install_mock_cache(t)
+        assert result_lines(t.render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        assert m.kwargs == {'data_dir':module_base, 'type':'dbm'}
+
+    def test_args_complete(self):
+        t = Template("""
+        <%%def name="foo()" cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'>
+            this is foo
+        </%%def>
+
+        ${foo()}
+""" % module_base)
+        m = self._install_mock_cache(t)
+        t.render()
+        assert m.kwargs == {'data_dir':module_base, 'type':'file', 'expiretime':30}
+        
+        t2 = Template("""
+        <%%page cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'/>
+        hi
+        """ % module_base)
+        m = self._install_mock_cache(t2)
+        t2.render()
+        assert m.kwargs == {'data_dir':module_base, 'type':'file', 'expiretime':30}
+
+    def test_fileargs_lookup(self):
+        l = lookup.TemplateLookup(cache_dir=module_base, cache_type='file')
+        l.put_string("test","""
+                <%!
+                    callcount = [0]
+                %>
+                <%def name="foo()" cached="True">
+                    this is foo
+                    <%
+                    callcount[0] += 1
+                    %>
+                </%def>
+
+                ${foo()}
+                ${foo()}
+                ${foo()}
+                callcount: ${callcount}
+        """)
+    
+        t = l.get_template('test')
+        m = self._install_mock_cache(t)
+        assert result_lines(l.get_template('test').render()) == [
+            'this is foo',
+            'this is foo',
+            'this is foo',
+            'callcount: [1]',
+        ]
+        assert m.kwargs == {'data_dir':module_base, 'type':'file'}
+    
+    def test_buffered(self):
+        t = Template("""
+        <%!
+            def a(text):
+                return "this is a " + text.strip()
+        %>
+        ${foo()}
+        ${foo()}
+        <%def name="foo()" cached="True" buffered="True">
+            this is a test
+        </%def>
+        """, buffer_filters=["a"])
+        assert result_lines(t.render()) == ["this is a this is a test", "this is a this is a test"]
+    
+    def test_load_from_expired(self):
+        """test that the cache callable can be called safely after the
+        originating template has completed rendering.
+        
+        """
+        t = Template("""
+        ${foo()}
+        <%def name="foo()" cached="True" cache_timeout="2">
+            foo
+        </%def>
+        """)
+        
+        import time
+        x1 = t.render()
+        time.sleep(3)
+        x2 = t.render()
+        assert x1.strip() == x2.strip() == "foo"
+    
+    def test_cache_uses_current_context(self):
+        t = Template("""
+        ${foo()}
+        <%def name="foo()" cached="True" cache_timeout="2">
+            foo: ${x}
+        </%def>
+        """)
+        
+        import time
+        x1 = t.render(x=1)
+        time.sleep(3)
+        x2 = t.render(x=2)
+        assert x1.strip() == "foo: 1"
+        assert x2.strip() == "foo: 2"
+
+    def test_namespace_access(self):
+        t = Template("""
+            <%def name="foo(x)" cached="True">
+                foo: ${x}
+            </%def>
+
+            <%
+                foo(1)
+                foo(2)
+                local.cache.invalidate_def('foo')
+                foo(3)
+                foo(4)
+            %>
+        """)
+        assert result_lines(t.render()) == ['foo: 1', 'foo: 1', 'foo: 3', 'foo: 3']
+        
+    def test_invalidate(self):
+        t = Template("""
+            <%%def name="foo()" cached="True">
+                foo: ${x}
+            </%%def>
+
+            <%%def name="bar()" cached="True" cache_type='dbm' cache_dir='%s'>
+                bar: ${x}
+            </%%def>
+            ${foo()} ${bar()}
+        """ % module_base)
+        assert result_lines(t.render(x=1)) == ["foo: 1", "bar: 1"]
+        assert result_lines(t.render(x=2)) == ["foo: 1", "bar: 1"]
+        t.cache.invalidate_def('foo')
+        assert result_lines(t.render(x=3)) == ["foo: 3", "bar: 1"]
+        t.cache.invalidate_def('bar')
+        assert result_lines(t.render(x=4)) == ["foo: 3", "bar: 4"]
+        
+        t = Template("""
+            <%%page cached="True" cache_type="dbm" cache_dir="%s"/>
+            
+            page: ${x}
+        """ % module_base)
+        assert result_lines(t.render(x=1)) == ["page: 1"]
+        assert result_lines(t.render(x=2)) == ["page: 1"]
+        t.cache.invalidate_body()
+        assert result_lines(t.render(x=3)) == ["page: 3"]
+        assert result_lines(t.render(x=4)) == ["page: 3"]
+        
+        
+    def _install_mock_cache(self, template):
+        m = MockCache(template.module._template_cache)
+        template.module._template_cache = m
+        return m
diff --git a/lib3/mako-0.3.6/test/test_call.py b/lib3/mako-0.3.6/test/test_call.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_call.py
@@ -0,0 +1,447 @@
+from mako.template import Template
+from mako import util
+from .util import result_lines, flatten_result
+from test import TemplateTest, eq_
+
+class CallTest(TemplateTest):
+    def test_call(self):
+        t = Template("""
+        <%def name="foo()">
+            hi im foo ${caller.body(y=5)}
+        </%def>
+        
+        <%call expr="foo()" args="y, **kwargs">
+            this is the body, y is ${y}
+        </%call>
+""")
+        assert result_lines(t.render()) == ['hi im foo', 'this is the body, y is 5']
+
+
+    def test_compound_call(self):
+        t = Template("""
+
+        <%def name="bar()">
+            this is bar
+        </%def>
+        
+        <%def name="comp1()">
+            this comp1 should not be called
+        </%def>
+        
+        <%def name="foo()">
+            foo calling comp1: ${caller.comp1(x=5)}
+            foo calling body: ${caller.body()}
+        </%def>
+        
+        <%call expr="foo()">
+            <%def name="comp1(x)">
+                this is comp1, ${x}
+            </%def>
+            this is the body, ${comp1(6)}
+        </%call>
+        ${bar()}
+
+""")
+        assert result_lines(t.render()) == ['foo calling comp1:', 'this is comp1, 5', 'foo calling body:', 'this is the body,', 'this is comp1, 6', 'this is bar']
+
+    def test_new_syntax(self):
+        """test foo:bar syntax, including multiline args and expression eval."""
+        
+        # note the trailing whitespace in the bottom ${} expr, need to strip
+        # that off < python 2.7
+        
+        t = Template("""
+            <%def name="foo(x, y, q, z)">
+                ${x}
+                ${y}
+                ${q}
+                ${",".join("%s->%s" % (a, b) for a, b in z)}
+            </%def>
+            
+            <%self:foo x="this is x" y="${'some ' + 'y'}" q="
+                this
+                is
+                q"
+                
+                z="${[
+                (1, 2),
+                (3, 4),
+                (5, 6)
+            ]
+            
+            }"/>
+        """)
+        
+        eq_(
+            result_lines(t.render()),
+             ['this is x', 'some y', 'this', 'is', 'q', '1->2,3->4,5->6']
+        )
+        
+    def test_ccall_caller(self):
+        t = Template("""
+        <%def name="outer_func()">
+        OUTER BEGIN
+            <%call expr="caller.inner_func()">
+                INNER CALL
+            </%call>
+        OUTER END
+        </%def>
+
+        <%call expr="outer_func()">
+            <%def name="inner_func()">
+                INNER BEGIN
+                ${caller.body()}
+                INNER END
+            </%def>
+        </%call>
+
+        """)
+        #print t.code
+        assert result_lines(t.render()) == [
+            "OUTER BEGIN",
+            "INNER BEGIN",
+            "INNER CALL",
+            "INNER END",
+            "OUTER END",
+        ]
+    
+    def test_stack_pop(self):
+        t = Template("""
+        <%def name="links()" buffered="True">
+           Some links
+        </%def>
+
+        <%def name="wrapper(links)">
+           <h1>${caller.body()}</h1>
+           ${links}
+        </%def>
+
+        ## links() pushes a stack frame on.  when complete,
+        ## 'nextcaller' must be restored
+        <%call expr="wrapper(links())">
+           Some title
+        </%call>
+
+        """)
+
+        assert result_lines(t.render()) == [
+        "<h1>",
+        "Some title",
+        "</h1>",
+        "Some links"
+        ]
+        
+    def test_conditional_call(self):
+        """test that 'caller' is non-None only if the immediate <%def> was called via <%call>"""
+
+        t = Template("""
+        <%def name="a()">
+        % if caller:
+        ${ caller.body() } \\
+        % endif
+        AAA
+        ${ b() }
+        </%def>
+
+        <%def name="b()">
+        % if caller:
+        ${ caller.body() } \\
+        % endif
+        BBB
+        ${ c() }
+        </%def>
+
+        <%def name="c()">
+        % if caller:
+        ${ caller.body() } \\
+        % endif
+        CCC
+        </%def>
+
+        <%call expr="a()">
+        CALL
+        </%call>
+
+        """)
+        assert result_lines(t.render()) == [
+            "CALL",
+            "AAA",
+            "BBB",
+            "CCC"
+        ]
+        
+    def test_chained_call(self):
+        """test %calls that are chained through their targets"""
+        t = Template("""
+            <%def name="a()">
+                this is a. 
+                <%call expr="b()">
+                    this is a's ccall.  heres my body: ${caller.body()}
+                </%call>
+            </%def>
+            <%def name="b()">
+                this is b.  heres  my body: ${caller.body()}
+                whats in the body's caller's body ?
+                ${context.caller_stack[-2].body()}
+            </%def>
+            
+            <%call expr="a()">
+                heres the main templ call
+            </%call>
+            
+""")
+        assert result_lines(t.render()) == [
+            'this is a.',
+            'this is b. heres my body:',
+            "this is a's ccall. heres my body:",
+            'heres the main templ call',
+            "whats in the body's caller's body ?",
+            'heres the main templ call'
+        ]
+
+    def test_nested_call(self):
+        """test %calls that are nested inside each other"""
+        t = Template("""
+            <%def name="foo()">
+                ${caller.body(x=10)}
+            </%def>
+
+            x is ${x}
+            <%def name="bar()">
+                bar: ${caller.body()}
+            </%def>
+
+            <%call expr="foo()" args="x">
+                this is foo body: ${x}
+
+                <%call expr="bar()">
+                    this is bar body: ${x}
+                </%call>
+            </%call>
+""")
+        assert result_lines(t.render(x=5)) == [
+            "x is 5",
+            "this is foo body: 10",
+            "bar:",
+            "this is bar body: 10"
+        ]
+        
+    def test_nested_call_2(self):
+        t = Template("""
+            x is ${x}
+            <%def name="foo()">
+                ${caller.foosub(x=10)}
+            </%def>
+
+            <%def name="bar()">
+                bar: ${caller.barsub()}
+            </%def>
+
+            <%call expr="foo()">
+                <%def name="foosub(x)">
+                this is foo body: ${x}
+                
+                <%call expr="bar()">
+                    <%def name="barsub()">
+                    this is bar body: ${x}
+                    </%def>
+                </%call>
+                
+                </%def>
+
+            </%call>
+""")
+        assert result_lines(t.render(x=5)) == [
+            "x is 5",
+            "this is foo body: 10",
+            "bar:",
+            "this is bar body: 10"
+        ]
+
+    def test_nested_call_3(self):
+        template = Template('''\
+        <%def name="A()">
+          ${caller.body()}
+        </%def>
+
+        <%def name="B()">
+          ${caller.foo()}
+        </%def>
+
+        <%call expr="A()">
+          <%call expr="B()">
+            <%def name="foo()">
+              foo
+            </%def>
+          </%call>
+        </%call>
+
+        ''')
+        assert flatten_result(template.render()) == "foo"
+        
+    def test_chained_call_in_nested(self):
+        t = Template("""
+            <%def name="embedded()">
+            <%def name="a()">
+                this is a. 
+                <%call expr="b()">
+                    this is a's ccall.  heres my body: ${caller.body()}
+                </%call>
+            </%def>
+            <%def name="b()">
+                this is b.  heres  my body: ${caller.body()}
+                whats in the body's caller's body ? ${context.caller_stack[-2].body()}
+            </%def>
+
+            <%call expr="a()">
+                heres the main templ call
+            </%call>
+            </%def>
+            ${embedded()}
+""")
+        #print t.code
+        #print result_lines(t.render())
+        assert result_lines(t.render()) == [
+            'this is a.',
+            'this is b. heres my body:',
+            "this is a's ccall. heres my body:",
+            'heres the main templ call',
+            "whats in the body's caller's body ?",
+            'heres the main templ call'
+        ]
+        
+    def test_call_in_nested(self):
+        t = Template("""
+            <%def name="a()">
+                this is a ${b()}
+                <%def name="b()">
+                    this is b
+                    <%call expr="c()">
+                        this is the body in b's call
+                    </%call>
+                </%def>
+                <%def name="c()">
+                    this is c: ${caller.body()}
+                </%def>
+            </%def>
+        ${a()}
+""")
+        assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call"]
+
+    def test_regular_defs(self):
+        t = Template("""
+        <%!
+            @runtime.supports_caller
+            def a(context):
+                context.write("this is a")
+                if context['caller']:
+                    context['caller'].body()
+                context.write("a is done")
+                return ''
+        %>
+        
+        <%def name="b()">
+            this is b
+            our body: ${caller.body()}
+            ${a(context)}
+        </%def>
+        test 1
+        <%call expr="a(context)">
+            this is the body
+        </%call>
+        test 2
+        <%call expr="b()">
+            this is the body
+        </%call>
+        test 3
+        <%call expr="b()">
+            this is the body
+            <%call expr="b()">
+                this is the nested body
+            </%call>
+        </%call>
+
+
+        """)    
+        #print t.code
+        assert result_lines(t.render()) == [
+            "test 1",
+            "this is a",
+            "this is the body",
+            "a is done",
+            "test 2",
+            "this is b",
+            "our body:",
+            "this is the body",
+            "this is aa is done",
+            "test 3",
+            "this is b",
+            "our body:",
+            "this is the body",
+            "this is b",
+            "our body:",
+            "this is the nested body",
+            "this is aa is done",
+            "this is aa is done"
+        ]
+        
+    def test_call_in_nested_2(self):
+        t = Template("""
+            <%def name="a()">
+                <%def name="d()">
+                    not this d
+                </%def>
+                this is a ${b()}
+                <%def name="b()">
+                    <%def name="d()">
+                        not this d either
+                    </%def>
+                    this is b
+                    <%call expr="c()">
+                        <%def name="d()">
+                            this is d
+                        </%def>
+                        this is the body in b's call
+                    </%call>
+                </%def>
+                <%def name="c()">
+                    this is c: ${caller.body()}
+                    the embedded "d" is: ${caller.d()}
+                </%def>
+            </%def>
+        ${a()}
+""")
+        assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call", 'the embedded "d" is:', 'this is d']
+
+class SelfCacheTest(TemplateTest):
+    """this test uses a now non-public API."""
+    
+    def test_basic(self):
+        t = Template("""
+        <%!
+            cached = None
+        %>
+        <%def name="foo()">
+            <% 
+                global cached
+                if cached:
+                    return "cached: " + cached
+                __M_writer = context._push_writer()
+            %>
+            this is foo
+            <%
+                buf, __M_writer = context._pop_buffer_and_writer()
+                cached = buf.getvalue()
+                return cached
+            %>
+        </%def>
+        
+        ${foo()}
+        ${foo()}
+""")
+        assert result_lines(t.render()) == [
+            "this is foo",
+            "cached:",
+            "this is foo"
+        ]
+        
diff --git a/lib3/mako-0.3.6/test/test_decorators.py b/lib3/mako-0.3.6/test/test_decorators.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_decorators.py
@@ -0,0 +1,110 @@
+from mako.template import Template
+from mako import lookup
+import unittest
+from .util import flatten_result, result_lines
+
+class DecoratorTest(unittest.TestCase):
+    def test_toplevel(self):
+        template = Template("""
+            <%!
+                def bar(fn):
+                    def decorate(context, *args, **kw):
+                        return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR"
+                    return decorate
+            %>
+            
+            <%def name="foo(y, x)" decorator="bar">
+                this is foo ${y} ${x}
+            </%def>
+            
+            ${foo(1, x=5)}
+        """)
+
+        assert flatten_result(template.render()) == "BAR this is foo 1 5 BAR"
+
+    def test_toplevel_contextual(self):
+        template = Template("""
+            <%!
+                def bar(fn):
+                    def decorate(context):
+                        context.write("BAR")
+                        fn()
+                        context.write("BAR")
+                        return ''
+                    return decorate
+            %>
+
+            <%def name="foo()" decorator="bar">
+                this is foo
+            </%def>
+
+            ${foo()}
+        """)
+
+        assert flatten_result(template.render()) == "BAR this is foo BAR"
+
+        assert flatten_result(template.get_def('foo').render()) == "BAR this is foo BAR"
+
+
+    def test_nested(self):
+        template = Template("""
+            <%!
+                def bat(fn):
+                    def decorate(context):
+                        return "BAT" + runtime.capture(context, fn) + "BAT"
+                    return decorate
+            %>
+
+            <%def name="foo()">
+            
+                <%def name="bar()" decorator="bat">
+                    this is bar
+                </%def>
+                ${bar()}
+            </%def>
+
+            ${foo()}
+        """)
+
+        assert flatten_result(template.render()) == "BAT this is bar BAT"
+        
+    def test_toplevel_decorated_name(self):
+        template = Template("""
+            <%!
+                def bar(fn):
+                    def decorate(context, *args, **kw):
+                        return "function " + fn.__name__ + " " + runtime.capture(context, fn, *args, **kw)
+                    return decorate
+            %>
+
+            <%def name="foo(y, x)" decorator="bar">
+                this is foo ${y} ${x}
+            </%def>
+
+            ${foo(1, x=5)}
+        """)
+
+        assert flatten_result(template.render()) == "function foo this is foo 1 5"
+
+    def test_nested_decorated_name(self):
+        template = Template("""
+            <%!
+                def bat(fn):
+                    def decorate(context):
+                        return "function " + fn.__name__ + " " + runtime.capture(context, fn)
+                    return decorate
+            %>
+
+            <%def name="foo()">
+
+                <%def name="bar()" decorator="bat">
+                    this is bar
+                </%def>
+                ${bar()}
+            </%def>
+
+            ${foo()}
+        """)
+
+        assert flatten_result(template.render()) == "function bar this is bar"
+        
diff --git a/lib3/mako-0.3.6/test/test_def.py b/lib3/mako-0.3.6/test/test_def.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_def.py
@@ -0,0 +1,550 @@
+from mako.template import Template
+from mako import lookup
+from test import TemplateTest
+from .util import flatten_result, result_lines
+
+class DefTest(TemplateTest):
+    def test_def_noargs(self):
+        template = Template("""
+        
+        ${mycomp()}
+        
+        <%def name="mycomp()">
+            hello mycomp ${variable}
+        </%def>
+        
+        """)
+        assert template.render(variable='hi').strip() == """hello mycomp hi"""
+
+    def test_def_blankargs(self):
+        template = Template("""
+        <%def name="mycomp()">
+            hello mycomp ${variable}
+        </%def>
+
+        ${mycomp()}""")
+        assert template.render(variable='hi').strip() == """hello mycomp hi"""
+
+    def test_def_args(self):
+        template = Template("""
+        <%def name="mycomp(a, b)">
+            hello mycomp ${variable}, ${a}, ${b}
+        </%def>
+
+        ${mycomp(5, 6)}""")
+        assert template.render(variable='hi', a=5, b=6).strip() == """hello mycomp hi, 5, 6"""
+
+    def test_inter_def(self):
+        """test defs calling each other"""
+        template = Template("""
+        ${b()}
+
+        <%def name="a()">\
+        im a
+        </%def>
+
+        <%def name="b()">
+        im b
+        and heres a:  ${a()}
+        </%def>
+
+        <%def name="c()">
+        im c
+        </%def>
+""")
+        # check that "a" is declared in "b", but not in "c"
+        assert "a" not in template.module.render_c.__code__.co_varnames
+        assert "a" in template.module.render_b.__code__.co_varnames
+        
+        # then test output
+        assert flatten_result(template.render()) == "im b and heres a: im a"
+
+    def test_toplevel(self):
+        """test calling a def from the top level"""
+
+        template = Template("""
+        
+            this is the body
+        
+            <%def name="a()">
+                this is a
+            </%def>
+
+            <%def name="b(x, y)">
+                this is b, ${x} ${y}
+            </%def>
+                
+        """)
+        
+        self._do_test(template.get_def("a"), "this is a", filters=flatten_result)
+        self._do_test(template.get_def("b"), "this is b, 10 15", 
+                                                            template_args={'x':10, 'y':15}, 
+                                                            filters=flatten_result)
+        self._do_test(template.get_def("body"), "this is the body", filters=flatten_result)
+        
+        # test that args outside of the dict can be used
+        self._do_test(template.get_def("a"), "this is a", 
+                        filters=flatten_result, template_args={'q':5,'zq':'test'})
+        
+class ScopeTest(TemplateTest):
+    """test scoping rules.  The key is, enclosing scope always takes precedence over contextual scope."""
+    
+    def test_scope_one(self):
+        self._do_memory_test("""
+        <%def name="a()">
+            this is a, and y is ${y}
+        </%def>
+
+        ${a()}
+
+        <%
+            y = 7
+        %>
+
+        ${a()}
+
+""",
+            "this is a, and y is None this is a, and y is 7",
+            filters=flatten_result,
+            template_args={'y':None}
+        )
+
+    def test_scope_two(self):
+        t = Template("""
+        y is ${y}
+
+        <%
+            y = 7
+        %>
+
+        y is ${y}
+""")
+        try:
+            t.render(y=None)
+            assert False
+        except UnboundLocalError:
+            assert True
+
+    def test_scope_four(self):
+        """test that variables are pulled from 'enclosing' scope before context."""
+        t = Template("""
+            <%
+                x = 5
+            %>
+            <%def name="a()">
+                this is a. x is ${x}.
+            </%def>
+            
+            <%def name="b()">
+                <%
+                    x = 9
+                %>
+                this is b. x is ${x}.
+                calling a. ${a()}
+            </%def>
+        
+            ${b()}
+""")
+        assert flatten_result(t.render()) == "this is b. x is 9. calling a. this is a. x is 5."
+    
+    def test_scope_five(self):
+        """test that variables are pulled from 'enclosing' scope before context."""
+        # same as test four, but adds a scope around it.
+        t = Template("""
+            <%def name="enclosing()">
+            <%
+                x = 5
+            %>
+            <%def name="a()">
+                this is a. x is ${x}.
+            </%def>
+
+            <%def name="b()">
+                <%
+                    x = 9
+                %>
+                this is b. x is ${x}.
+                calling a. ${a()}
+            </%def>
+
+            ${b()}
+            </%def>
+            ${enclosing()}
+""")
+        assert flatten_result(t.render()) == "this is b. x is 9. calling a. this is a. x is 5."
+
+    def test_scope_six(self):
+        """test that the initial context counts as 'enclosing' scope, for plain defs"""
+        t = Template("""
+
+        <%def name="a()">
+            a: x is ${x}
+        </%def>
+
+        <%def name="b()">
+            <%
+                x = 10
+            %>
+            b. x is ${x}.  ${a()}
+        </%def>
+
+        ${b()}
+    """)
+        assert flatten_result(t.render(x=5)) == "b. x is 10. a: x is 5"
+
+    def test_scope_seven(self):
+        """test that the initial context counts as 'enclosing' scope, for nested defs"""
+        t = Template("""
+        <%def name="enclosing()">
+            <%def name="a()">
+                a: x is ${x}
+            </%def>
+
+            <%def name="b()">
+                <%
+                    x = 10
+                %>
+                b. x is ${x}.  ${a()}
+            </%def>
+
+            ${b()}
+        </%def>
+        ${enclosing()}
+    """)
+        assert flatten_result(t.render(x=5)) == "b. x is 10. a: x is 5"
+
+    def test_scope_eight(self):
+        """test that the initial context counts as 'enclosing' scope, for nested defs"""
+        t = Template("""
+        <%def name="enclosing()">
+            <%def name="a()">
+                a: x is ${x}
+            </%def>
+
+            <%def name="b()">
+                <%
+                    x = 10
+                %>
+                
+                b. x is ${x}.  ${a()}
+            </%def>
+
+            ${b()}
+        </%def>
+        ${enclosing()}
+    """)
+        assert flatten_result(t.render(x=5)) == "b. x is 10. a: x is 5"
+
+    def test_scope_nine(self):
+        """test that 'enclosing scope' doesnt get exported to other templates"""
+        
+        l = lookup.TemplateLookup()
+        l.put_string('main', """
+        <%
+            x = 5
+        %>
+        this is main.  <%include file="secondary"/>
+""")
+
+        l.put_string('secondary', """
+        this is secondary.  x is ${x}
+""")
+
+        assert flatten_result(l.get_template('main').render(x=2)) == "this is main. this is secondary. x is 2"
+        
+    def test_scope_ten(self):
+        t = Template("""
+            <%def name="a()">
+                <%def name="b()">
+                    <%
+                        y = 19
+                    %>
+                    b/c: ${c()}
+                    b/y: ${y}
+                </%def>
+                <%def name="c()">
+                    c/y: ${y}
+                </%def>
+
+                <%
+                    # we assign to "y".  but the 'enclosing scope' of "b" and "c" is from the "y" on the outside
+                    y = 10
+                %>
+                a/y: ${y}
+                a/b: ${b()}
+            </%def>
+
+            <%
+                y = 7
+            %>
+            main/a: ${a()}
+            main/y: ${y}
+    """)
+        assert flatten_result(t.render()) == "main/a: a/y: 10 a/b: b/c: c/y: 10 b/y: 19 main/y: 7"
+
+    def test_scope_eleven(self):
+        t = Template("""
+            x is ${x}
+            <%def name="a(x)">
+                this is a, ${b()}
+                <%def name="b()">
+                    this is b, x is ${x}
+                </%def>
+            </%def>
+            
+            ${a(x=5)}
+""")
+        assert result_lines(t.render(x=10)) == [
+            "x is 10",
+            "this is a,", 
+            "this is b, x is 5"
+        ]
+
+    def test_unbound_scope(self):
+        t = Template("""
+            <%
+                y = 10
+            %>
+            <%def name="a()">
+                y is: ${y}
+                <%
+                    # should raise error ?
+                    y = 15
+                %>
+                y is ${y}
+            </%def>
+            ${a()}
+""")
+        try:
+            print(t.render())
+            assert False
+        except UnboundLocalError:
+            assert True
+
+    def test_unbound_scope_two(self):
+        t = Template("""
+            <%def name="enclosing()">
+            <%
+                y = 10
+            %>
+            <%def name="a()">
+                y is: ${y}
+                <%
+                    # should raise error ?
+                    y = 15
+                %>
+                y is ${y}
+            </%def>
+            ${a()}
+            </%def>
+            ${enclosing()}
+""")
+        try:
+            print(t.render())
+            assert False
+        except UnboundLocalError:
+            assert True
+
+    def test_canget_kwargs(self):
+        """test that arguments passed to the body() function are accessible by top-level defs"""
+        l = lookup.TemplateLookup()
+        l.put_string("base", """
+        
+        ${next.body(x=12)}
+        
+        """)
+        
+        l.put_string("main", """
+            <%inherit file="base"/>
+            <%page args="x"/>
+            this is main.  x is ${x}
+            
+            ${a()}
+            
+            <%def name="a(**args)">
+                this is a, x is ${x}
+            </%def>
+        """)
+        
+        # test via inheritance
+        #print l.get_template("main").code
+        assert result_lines(l.get_template("main").render()) == [
+            "this is main. x is 12",
+            "this is a, x is 12"
+        ]
+
+        l.put_string("another", """
+            <%namespace name="ns" file="main"/>
+            
+            ${ns.body(x=15)}
+        """)
+        # test via namespace
+        assert result_lines(l.get_template("another").render()) == [
+            "this is main. x is 15",
+            "this is a, x is 15"
+        ]
+
+class NestedDefTest(TemplateTest):
+    def test_nested_def(self):
+        t = Template("""
+
+        ${hi()}
+        
+        <%def name="hi()">
+            hey, im hi.
+            and heres ${foo()}, ${bar()}
+            
+            <%def name="foo()">
+                this is foo
+            </%def>
+            
+            <%def name="bar()">
+                this is bar
+            </%def>
+        </%def>
+""")
+        assert flatten_result(t.render()) == "hey, im hi. and heres this is foo , this is bar"
+
+    def test_nested_2(self):
+        t = Template("""
+            x is ${x}
+            <%def name="a()">
+                this is a, x is ${x}
+                ${b()}
+                <%def name="b()">
+                    this is b: ${x}
+                </%def>
+            </%def>
+            ${a()}
+""")
+        
+        assert flatten_result(t.render(x=10)) == "x is 10 this is a, x is 10 this is b: 10"
+        
+    def test_nested_with_args(self):
+        t = Template("""
+        ${a()}
+        <%def name="a()">
+            <%def name="b(x, y=2)">
+                b x is ${x} y is ${y}
+            </%def>
+            a ${b(5)}
+        </%def>
+""")
+        assert flatten_result(t.render()) == "a b x is 5 y is 2"
+        
+    def test_nested_def_2(self):
+        template = Template("""
+        ${a()}
+        <%def name="a()">
+            <%def name="b()">
+                <%def name="c()">
+                    comp c
+                </%def>
+                ${c()}
+            </%def>
+            ${b()}
+        </%def>
+""")
+        assert flatten_result(template.render()) == "comp c"
+
+    def test_nested_nested_def(self):
+        t = Template("""
+        
+        ${a()}
+        <%def name="a()">
+            a
+            <%def name="b1()">
+                a_b1
+            </%def>
+            <%def name="b2()">
+                a_b2 ${c1()}
+                <%def name="c1()">
+                    a_b2_c1
+                </%def>
+            </%def>
+            <%def name="b3()">
+                a_b3 ${c1()}
+                <%def name="c1()">
+                    a_b3_c1 heres x: ${x}
+                    <%
+                        y = 7
+                    %>
+                    y is ${y}
+                </%def>
+                <%def name="c2()">
+                    a_b3_c2
+                    y is ${y}
+                    c1 is ${c1()}
+                </%def>
+                ${c2()}
+            </%def>
+            
+            ${b1()} ${b2()}  ${b3()}
+        </%def>
+""")
+        assert flatten_result(t.render(x=5, y=None)) == "a a_b1 a_b2 a_b2_c1 a_b3 a_b3_c1 heres x: 5 y is 7 a_b3_c2 y is None c1 is a_b3_c1 heres x: 5 y is 7"
+    
+    def test_nested_nested_def_2(self):
+        t = Template("""
+        <%def name="a()">
+            this is a ${b()}
+            <%def name="b()">
+                this is b
+                ${c()}
+            </%def>
+            
+            <%def name="c()">
+                this is c
+            </%def>
+        </%def>
+        ${a()}
+""" )
+        assert flatten_result(t.render()) == "this is a this is b this is c"
+
+    def test_outer_scope(self):
+        t = Template("""
+        <%def name="a()">
+            a: x is ${x}
+        </%def>
+
+        <%def name="b()">
+            <%def name="c()">
+            <%
+                x = 10
+            %>
+            c. x is ${x}.  ${a()}
+            </%def>
+            
+            b. ${c()}
+        </%def>
+
+        ${b()}
+        
+        x is ${x}
+""")
+        assert flatten_result(t.render(x=5)) == "b. c. x is 10. a: x is 5 x is 5"
+            
+class ExceptionTest(TemplateTest):
+    def test_raise(self):
+        template = Template("""
+            <%
+                raise Exception("this is a test")
+            %>
+    """, format_exceptions=False)
+        try:
+            template.render()
+            assert False
+        except Exception as e:
+            assert str(e) == "this is a test"
+    def test_handler(self):
+        def handle(context, error):
+            context.write("error message is " + str(error))
+            return True
+            
+        template = Template("""
+            <%
+                raise Exception("this is a test")
+            %>
+    """, error_handler=handle)
+        assert template.render().strip() == """error message is this is a test"""
+        
diff --git a/lib3/mako-0.3.6/test/test_exceptions.py b/lib3/mako-0.3.6/test/test_exceptions.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_exceptions.py
@@ -0,0 +1,188 @@
+# -*- coding: utf-8 -*-
+import sys
+import unittest
+
+from mako import exceptions, util
+from mako.template import Template
+from mako.lookup import TemplateLookup
+from .util import result_lines
+from test import template_base, module_base, TemplateTest
+
+class ExceptionsTest(TemplateTest):
+    def test_html_error_template(self):
+        """test the html_error_template"""
+        code = """
+% i = 0
+"""
+        try:
+            template = Template(code)
+            template.render_unicode()
+            assert False
+        except exceptions.CompileException as ce:
+            html_error = exceptions.html_error_template().render_unicode()
+            assert ("CompileException: Fragment 'i = 0' is not a partial "
+                    "control statement") in html_error
+            assert '<style>' in html_error
+            html_error_stripped = html_error.strip()
+            assert html_error_stripped.startswith('<html>')
+            assert html_error_stripped.endswith('</html>')
+
+            not_full = exceptions.html_error_template().\
+                                    render_unicode(full=False)
+            assert '<html>' not in not_full
+            assert '<style>' in not_full
+
+            no_css = exceptions.html_error_template().\
+                                    render_unicode(css=False)
+            assert '<style>' not in no_css
+        else:
+            assert False, ("This function should trigger a CompileException, "
+                           "but didn't")
+
+    def test_text_error_template(self):
+        code = """
+% i = 0
+"""
+        try:
+            template = Template(code)
+            template.render_unicode()
+            assert False
+        except exceptions.CompileException as ce:
+            text_error = exceptions.text_error_template().render_unicode()
+            assert 'Traceback (most recent call last):' in text_error
+            assert ("CompileException: Fragment 'i = 0' is not a partial "
+                    "control statement") in text_error
+
+        
+    def test_utf8_html_error_template(self):
+        """test the html_error_template with a Template containing utf8
+        chars"""
+        
+        if util.py3k:
+            code = """# -*- coding: utf-8 -*-
+% if 2 == 2: /an error
+${'привет'}
+% endif
+"""
+        else:
+            code = """# -*- coding: utf-8 -*-
+% if 2 == 2: /an error
+${u'привет'}
+% endif
+"""
+        try:
+            template = Template(code)
+            template.render_unicode()
+        except exceptions.CompileException as ce:
+            html_error = exceptions.html_error_template().render()
+            assert ("CompileException: Fragment 'if 2 == 2: /an "
+                    "error' is not a partial control "
+                    "statement at line: 2 char: 1") in \
+                    html_error.decode('utf-8')
+                    
+            if util.py3k:
+                assert "3 ${'привет'}".encode(sys.getdefaultencoding(),
+                                            'htmlentityreplace') in html_error
+            else:
+                assert "3 ${u'привет'}".encode(sys.getdefaultencoding(),
+                                            'htmlentityreplace') in html_error
+        else:
+            assert False, ("This function should trigger a CompileException, "
+                           "but didn't")
+    
+    def test_format_closures(self):
+        try:
+            exec("def foo():"\
+                 "    raise RuntimeError('test')", locals())
+            foo()
+        except:
+            html_error = exceptions.html_error_template().render()
+            assert "RuntimeError: test" in str(html_error)
+        
+    def test_py_utf8_html_error_template(self):
+        try:
+            foo = '日本'
+            raise RuntimeError('test')
+        except:
+            html_error = exceptions.html_error_template().render()
+            if util.py3k:
+                assert 'RuntimeError: test' in html_error.decode('utf-8')
+                assert "foo = '日本'" in html_error.decode('utf-8')
+            else:
+                assert 'RuntimeError: test' in html_error
+                assert "foo = u'&#x65E5;&#x672C;'" in html_error
+
+    def test_py_unicode_error_html_error_template(self):
+        try:
+            raise RuntimeError('日本')
+        except:
+            html_error = exceptions.html_error_template().render()
+            assert "RuntimeError: 日本".encode('ascii', 'ignore') in html_error
+
+    def test_format_exceptions(self):
+        l = TemplateLookup(format_exceptions=True)
+
+        l.put_string("foo.html", """
+<%inherit file="base.html"/>
+${foobar}
+        """)
+
+        l.put_string("base.html", """
+        ${self.body()}
+        """)
+
+        assert '<div class="sourceline">${foobar}</div>' in \
+                result_lines(l.get_template("foo.html").render_unicode())
+    
+    def test_utf8_format_exceptions(self):
+        """test that htmlentityreplace formatting is applied to 
+           exceptions reported with format_exceptions=True"""
+        
+        l = TemplateLookup(format_exceptions=True)
+        if util.py3k:
+            l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${'привет' + foobar}""")
+        else:
+            l.put_string("foo.html", """# -*- coding: utf-8 -*-\n${u'привет' + foobar}""")
+
+        if util.py3k:
+            assert '<div class="sourceline">${'привет' + foobar}</div>'\
+                in result_lines(l.get_template("foo.html").render().decode('utf-8'))
+        else:
+            assert '<div class="highlight">2 ${u'&#x43F;&#x440;'\
+                    '&#x438;&#x432;&#x435;&#x442;' + foobar}</div>' \
+                in result_lines(l.get_template("foo.html").render().decode('utf-8'))
+        
+    
+    def test_custom_tback(self):
+        try:
+            raise RuntimeError("error 1")
+            foo('bar')
+        except:
+            t, v, tback = sys.exc_info()
+        
+        try:
+            raise RuntimeError("error 2")
+        except:
+            html_error = exceptions.html_error_template().\
+                        render_unicode(error=v, traceback=tback)
+        
+        # obfuscate the text so that this text
+        # isn't in the 'wrong' exception
+        assert "".join(reversed(");93#&rab;93#&(oof")) in html_error
+
+    def test_tback_no_trace(self):
+        try:
+            t = self._file_template("runtimeerr.html")
+            t.render()
+        except:
+            t, v, tback = sys.exc_info()
+
+        if not util.py3k:
+            # blow away tracebaack info
+            sys.exc_clear()
+        
+        # and don't even send what we have.
+        html_error = exceptions.html_error_template().\
+                    render_unicode(error=v, traceback=None)
+        
+        assert "local variable 'y' referenced" in html_error
diff --git a/lib3/mako-0.3.6/test/test_filters.py b/lib3/mako-0.3.6/test/test_filters.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_filters.py
@@ -0,0 +1,290 @@
+# -*- coding: utf-8 -*-
+
+from mako.template import Template
+import unittest
+from mako import util
+from test import TemplateTest, eq_, skip_if
+from .util import result_lines, flatten_result
+
+class FilterTest(TemplateTest):
+    def test_basic(self):
+        t = Template("""
+        ${x | myfilter}
+""")
+        assert flatten_result(t.render(x="this is x", myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t)) == "MYFILTER->this is x<-MYFILTER"
+
+    def test_expr(self):
+        """test filters that are themselves expressions"""
+        t = Template("""
+        ${x | myfilter(y)}
+""")
+        def myfilter(y):
+            return lambda x: "MYFILTER->%s<-%s" % (x, y)
+        assert flatten_result(t.render(x="this is x", myfilter=myfilter, y="this is y")) == "MYFILTER->this is x<-this is y"
+
+    def test_convert_str(self):
+        """test that string conversion happens in expressions before sending to filters"""
+        t = Template("""
+            ${x | trim}
+        """)
+        assert flatten_result(t.render(x=5)) == "5"
+    
+    def test_quoting(self):
+        t = Template("""
+            foo ${bar | h}
+        """)
+        
+        eq_(
+            flatten_result(t.render(bar="<'some bar'>")),
+            "foo <'some bar'>"
+        )
+    
+    @skip_if(lambda: util.py3k)
+    def test_quoting_non_unicode(self):
+        t = Template("""
+            foo ${bar | h}
+        """, disable_unicode=True)
+
+        eq_(
+            flatten_result(t.render(bar="<'привет'>")),
+            "foo <'привет'>"
+        )
+        
+        
+    def test_def(self):
+        t = Template("""
+            <%def name="foo()" filter="myfilter">
+                this is foo
+            </%def>
+            ${foo()}
+""")
+
+        assert flatten_result(t.render(x="this is x", myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t)) == "MYFILTER-> this is foo <-MYFILTER"
+
+    def test_import(self):
+        t = Template("""
+        <%!
+            from mako import filters
+        %>\
+        trim this string: ${"  some string to trim   " | filters.trim} continue\
+        """)
+
+        assert t.render().strip()=="trim this string: some string to trim continue"
+    
+    def test_import_2(self):
+        t = Template("""
+        trim this string: ${"  some string to trim   " | filters.trim} continue\
+        """, imports=["from mako import filters"])
+        #print t.code
+        assert t.render().strip()=="trim this string: some string to trim continue"
+
+    def test_encode_filter(self):
+        t = Template("""# coding: utf-8
+            some stuff.... ${x}
+        """, default_filters=['decode.utf8'])
+        #print t.code
+        assert t.render_unicode(x="voix m’a réveillé").strip() == "some stuff.... voix m’a réveillé"
+        
+    def test_custom_default(self):
+        t = Template("""
+        <%!
+            def myfilter(x):
+                return "->" + x + "<-"
+        %>
+        
+            hi ${'there'}
+        """, default_filters=['myfilter'])
+        assert t.render().strip()=="hi ->there<-"
+        
+    def test_global(self):
+        t = Template("""
+            <%page expression_filter="h"/>
+            ${"<tag>this is html</tag>"}
+        """)
+        assert t.render().strip()  == "<tag>this is html</tag>"
+
+    def test_nflag(self):
+        t = Template("""
+            ${"<tag>this is html</tag>" | n}
+        """, default_filters=['h', 'unicode'])
+        assert t.render().strip()  == "<tag>this is html</tag>"
+
+        t = Template("""
+            <%page expression_filter="h"/>
+            ${"<tag>this is html</tag>" | n}
+        """)
+        assert t.render().strip()  == "<tag>this is html</tag>"
+
+        t = Template("""
+            <%page expression_filter="h"/>
+            ${"<tag>this is html</tag>" | n, h}
+        """)
+        assert t.render().strip()  == "<tag>this is html</tag>"
+    
+    def testnonexpression(self):
+        t = Template("""
+        <%!
+            def a(text):
+                return "this is a"
+            def b(text):
+                return "this is b"
+        %>
+        
+        ${foo()}
+        <%def name="foo()" buffered="True">
+            this is text
+        </%def>
+        """, buffer_filters=['a'])
+        assert t.render().strip() == "this is a"
+
+        t = Template("""
+        <%!
+            def a(text):
+                return "this is a"
+            def b(text):
+                return "this is b"
+        %>
+        
+        ${'hi'}
+        ${foo()}
+        <%def name="foo()" buffered="True">
+            this is text
+        </%def>
+        """, buffer_filters=['a'], default_filters=['b'])
+        assert flatten_result(t.render()) == "this is b this is b"
+
+        t = Template("""
+        <%!
+            class Foo(object):
+                foo = True
+                def __str__(self):
+                    return "this is a"
+            def a(text):
+                return Foo()
+            def b(text):
+                if hasattr(text, 'foo'):
+                    return str(text)
+                else:
+                    return "this is b"
+        %>
+        
+        ${'hi'}
+        ${foo()}
+        <%def name="foo()" buffered="True">
+            this is text
+        </%def>
+        """, buffer_filters=['a'], default_filters=['b'])
+        assert flatten_result(t.render()) == "this is b this is a"
+
+        t = Template("""
+        <%!
+            def a(text):
+                return "this is a"
+            def b(text):
+                return "this is b"
+        %>
+        
+        ${foo()}
+        ${bar()}
+        <%def name="foo()" filter="b">
+            this is text
+        </%def>
+        <%def name="bar()" filter="b" buffered="True">
+            this is text
+        </%def>
+        """, buffer_filters=['a'])
+        assert flatten_result(t.render()) == "this is b this is a"
+
+        
+    def test_builtins(self):
+        t = Template("""
+            ${"this is <text>" | h}
+""")
+        assert flatten_result(t.render()) == "this is <text>"
+        
+        t = Template("""
+            http://foo.com/arg1=${"hi! this is a string." | u}
+""")
+        assert flatten_result(t.render()) == "http://foo.com/arg1=hi%21+this+is+a+string."
+
+class BufferTest(unittest.TestCase):        
+    def test_buffered_def(self):
+        t = Template("""
+            <%def name="foo()" buffered="True">
+                this is foo
+            </%def>
+            ${"hi->" + foo() + "<-hi"}
+""")
+        assert flatten_result(t.render()) == "hi-> this is foo <-hi"
+
+    def test_unbuffered_def(self):
+        t = Template("""
+            <%def name="foo()" buffered="False">
+                this is foo
+            </%def>
+            ${"hi->" + foo() + "<-hi"}
+""")
+        assert flatten_result(t.render()) == "this is foo hi-><-hi"
+
+    def test_capture(self):
+        t = Template("""
+            <%def name="foo()" buffered="False">
+                this is foo
+            </%def>
+            ${"hi->" + capture(foo) + "<-hi"}
+""")
+        assert flatten_result(t.render()) == "hi-> this is foo <-hi"
+
+    def test_capture_exception(self):
+        template = Template("""
+            <%def name="a()">
+                this is a
+                <% 
+                    raise TypeError("hi")
+                %>
+            </%def>
+            <%
+                c = capture(a)
+            %>
+            a->${c}<-a
+        """)
+        try:
+            template.render()
+            assert False
+        except TypeError:
+            assert True
+    
+    def test_buffered_exception(self):
+        template = Template("""
+            <%def name="a()" buffered="True">
+                <%
+                    raise TypeError("hi")
+                %>
+            </%def>
+            
+            ${a()}
+            
+""") 
+        try:
+            print(template.render())
+            assert False
+        except TypeError:
+            assert True
+            
+    def test_capture_ccall(self):
+        t = Template("""
+            <%def name="foo()">
+                <%
+                    x = capture(caller.body)
+                %>
+                this is foo.  body: ${x}
+            </%def>
+
+            <%call expr="foo()">
+                ccall body
+            </%call>
+""")
+        
+        #print t.render()
+        assert flatten_result(t.render()) == "this is foo. body: ccall body"
+        
diff --git a/lib3/mako-0.3.6/test/test_inheritance.py b/lib3/mako-0.3.6/test/test_inheritance.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_inheritance.py
@@ -0,0 +1,350 @@
+from mako.template import Template
+from mako import lookup, util
+import unittest
+from .util import flatten_result, result_lines
+
+class InheritanceTest(unittest.TestCase):
+    def test_basic(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main', """
+<%inherit file="base"/>
+
+<%def name="header()">
+    main header.
+</%def>
+
+this is the content.
+""")
+
+        collection.put_string('base', """
+This is base.
+
+header: ${self.header()}
+
+body: ${self.body()}
+
+footer: ${self.footer()}
+
+<%def name="footer()">
+    this is the footer. header again ${next.header()}
+</%def>
+""")
+
+        assert result_lines(collection.get_template('main').render()) == [
+            'This is base.',
+             'header:',
+             'main header.',
+             'body:',
+             'this is the content.',
+             'footer:',
+             'this is the footer. header again',
+             'main header.'
+        ]
+
+    def test_multilevel_nesting(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main', """
+<%inherit file="layout"/>
+<%def name="d()">main_d</%def>
+main_body ${parent.d()}
+full stack from the top:
+    ${self.name} ${parent.name} ${parent.context['parent'].name} ${parent.context['parent'].context['parent'].name}
+""")
+        
+        collection.put_string('layout', """
+<%inherit file="general"/>
+<%def name="d()">layout_d</%def>
+layout_body
+parent name: ${parent.name}
+${parent.d()}
+${parent.context['parent'].d()}
+${next.body()}
+""")
+
+        collection.put_string('general', """
+<%inherit file="base"/>
+<%def name="d()">general_d</%def>
+general_body
+${next.d()}
+${next.context['next'].d()}
+${next.body()}
+""")
+        collection.put_string('base', """
+base_body
+full stack from the base:
+    ${self.name} ${self.context['parent'].name} ${self.context['parent'].context['parent'].name} ${self.context['parent'].context['parent'].context['parent'].name}
+${next.body()}
+<%def name="d()">base_d</%def>
+""")
+
+        assert result_lines(collection.get_template('main').render()) == [
+            'base_body',
+             'full stack from the base:',
+             'self:main self:layout self:general self:base',
+             'general_body',
+             'layout_d',
+             'main_d',
+             'layout_body',
+             'parent name: self:general',
+             'general_d',
+             'base_d',
+             'main_body layout_d',
+             'full stack from the top:',
+             'self:main self:layout self:general self:base'
+        ]
+        
+    def test_includes(self):
+        """test that an included template also has its full hierarchy invoked."""
+        collection = lookup.TemplateLookup()
+        
+        collection.put_string("base", """
+        <%def name="a()">base_a</%def>
+        This is the base.
+        ${next.body()}
+        End base.
+""")
+
+        collection.put_string("index","""
+        <%inherit file="base"/>
+        this is index.
+        a is: ${self.a()}
+        <%include file="secondary"/>
+""")
+
+        collection.put_string("secondary","""
+        <%inherit file="base"/>
+        this is secondary.
+        a is: ${self.a()}
+""")
+
+        assert result_lines(collection.get_template("index").render()) == [
+            'This is the base.', 
+            'this is index.',
+             'a is: base_a',
+             'This is the base.',
+             'this is secondary.',
+             'a is: base_a',
+             'End base.',
+             'End base.'
+            ]
+
+    def test_namespaces(self):
+        """test that templates used via <%namespace> have access to an inheriting 'self', and that
+        the full 'self' is also exported."""
+        collection = lookup.TemplateLookup()
+        
+        collection.put_string("base", """
+        <%def name="a()">base_a</%def>
+        <%def name="b()">base_b</%def>
+        This is the base.
+        ${next.body()}
+""")
+
+        collection.put_string("layout", """
+        <%inherit file="base"/>
+        <%def name="a()">layout_a</%def>
+        This is the layout..
+        ${next.body()}
+""")
+
+        collection.put_string("index","""
+        <%inherit file="base"/>
+        <%namespace name="sc" file="secondary"/>
+        this is index.
+        a is: ${self.a()}
+        sc.a is: ${sc.a()}
+        sc.b is: ${sc.b()}
+        sc.c is: ${sc.c()}
+        sc.body is: ${sc.body()}
+""")
+
+        collection.put_string("secondary","""
+        <%inherit file="layout"/>
+        <%def name="c()">secondary_c.  a is ${self.a()} b is ${self.b()} d is ${self.d()}</%def>
+        <%def name="d()">secondary_d.</%def>
+        this is secondary.
+        a is: ${self.a()}
+        c is: ${self.c()}
+""")
+
+        assert result_lines(collection.get_template('index').render()) ==  ['This is the base.',
+         'this is index.',
+         'a is: base_a',
+         'sc.a is: layout_a',
+         'sc.b is: base_b',
+         'sc.c is: secondary_c. a is layout_a b is base_b d is secondary_d.',
+         'sc.body is:',
+         'this is secondary.',
+         'a is: layout_a',
+         'c is: secondary_c. a is layout_a b is base_b d is secondary_d.'
+         ]
+
+    def test_pageargs(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+
+            <%
+            sorted_ = pageargs.items()
+            sorted_ = sorted(sorted_)
+            %>
+            pageargs: (type: ${type(pageargs)}) ${sorted_}
+            <%def name="foo()">
+                ${next.body(**context.kwargs)}
+            </%def>
+            
+            ${foo()}
+        """)
+        collection.put_string("index", """
+            <%inherit file="base"/>
+            <%page args="x, y, z=7"/>
+            print ${x}, ${y}, ${z}
+        """)
+        
+        if util.py3k:
+            assert result_lines(collection.get_template('index').render_unicode(x=5,y=10)) == [
+                "this is the base.",
+                "pageargs: (type: <class 'dict'>) [('x', 5), ('y', 10)]",
+                "print 5, 10, 7"
+            ]
+        else:
+            assert result_lines(collection.get_template('index').render_unicode(x=5,y=10)) == [
+                "this is the base.",
+                "pageargs: (type: <type 'dict'>) [('x', 5), ('y', 10)]",
+                "print 5, 10, 7"
+            ]
+        
+    def test_pageargs_2(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+            
+            ${next.body(**context.kwargs)}
+            
+            <%def name="foo(**kwargs)">
+                ${next.body(**kwargs)}
+            </%def>
+
+            <%def name="bar(**otherargs)">
+                ${next.body(z=16, **context.kwargs)}
+            </%def>
+
+            ${foo(x=12, y=15, z=8)}
+            ${bar(x=19, y=17)}
+        """)
+        collection.put_string("index", """
+            <%inherit file="base"/>
+            <%page args="x, y, z=7"/>
+            pageargs: ${x}, ${y}, ${z}
+        """)
+        assert result_lines(collection.get_template('index').render(x=5,y=10)) == [
+            "this is the base.",
+            "pageargs: 5, 10, 7",
+            "pageargs: 12, 15, 8",
+            "pageargs: 5, 10, 16"
+        ]
+    
+    def test_pageargs_err(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+            ${next.body()}
+        """)
+        collection.put_string("index", """
+            <%inherit file="base"/>
+            <%page args="x, y, z=7"/>
+            print ${x}, ${y}, ${z}
+        """)
+        try:
+            print(collection.get_template('index').render(x=5,y=10))
+            assert False
+        except TypeError:
+            assert True
+    
+    def test_toplevel(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+            ${next.body()}
+        """)
+        collection.put_string("index", """
+            <%inherit file="base"/>
+            this is the body
+        """)
+        assert result_lines(collection.get_template('index').render()) == [
+            "this is the base.",
+            "this is the body"
+        ]
+        assert result_lines(collection.get_template('index').get_def("body").render()) == [
+            "this is the body"
+        ]
+
+    def test_dynamic(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base", """
+            this is the base.
+            ${next.body()}
+        """)
+        collection.put_string("index", """
+            <%!
+                def dyn(context):
+                    if context.get('base', None) is not None:
+                        return 'base'
+                    else:
+                        return None
+            %>
+            <%inherit file="${dyn(context)}"/>
+            this is index.
+        """)
+        assert result_lines(collection.get_template('index').render()) == [
+            'this is index.'
+        ]
+        assert result_lines(collection.get_template('index').render(base=True)) == [
+            'this is the base.',
+            'this is index.'
+        ]
+        
+    def test_in_call(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("/layout.html","""
+        Super layout!
+        <%call expr="self.grid()">
+            ${next.body()}
+        </%call>
+        Oh yea!
+
+        <%def name="grid()">
+            Parent grid
+                ${caller.body()}
+            End Parent
+        </%def>
+        """)
+
+
+        collection.put_string("/subdir/layout.html", """
+        ${next.body()}
+        <%def name="grid()">
+           Subdir grid
+               ${caller.body()}
+           End subdir
+        </%def>
+        <%inherit file="/layout.html"/>
+        """)
+        
+        collection.put_string("/subdir/renderedtemplate.html","""
+        Holy smokes!
+        <%inherit file="/subdir/layout.html"/>
+        """)
+
+        #print collection.get_template("/layout.html").code
+        #print collection.get_template("/subdir/renderedtemplate.html").render()
+        assert result_lines(collection.get_template("/subdir/renderedtemplate.html").render()) == [
+            "Super layout!",
+            "Subdir grid",
+            "Holy smokes!",
+            "End subdir",
+            "Oh yea!"
+        ]
+
diff --git a/lib3/mako-0.3.6/test/test_lexer.py b/lib3/mako-0.3.6/test/test_lexer.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_lexer.py
@@ -0,0 +1,854 @@
+import unittest
+
+from mako.lexer import Lexer
+from mako import exceptions, util
+from .util import flatten_result, result_lines
+from mako.template import Template
+import re
+from test import TemplateTest, template_base, skip_if, eq_, assert_raises_message
+
+# create fake parsetree classes which are constructed
+# exactly as the repr() of a real parsetree object.
+# this allows us to use a Python construct as the source
+# of a comparable repr(), which is also hit by the 2to3 tool.
+
+def repr_arg(x):
+    if isinstance(x, dict):
+        return util.sorted_dict_repr(x)
+    else:
+        return repr(x)
+
+from mako import parsetree
+for cls in list(parsetree.__dict__.values()):
+    if isinstance(cls, type) and \
+        issubclass(cls, parsetree.Node):
+        clsname = cls.__name__
+        exec(("""
+class %s(object):
+    def __init__(self, *args):
+        self.args = args
+    def __repr__(self):
+        return "%%s(%%s)" %% (
+            self.__class__.__name__,
+            ", ".join(repr_arg(x) for x in self.args)
+            )
+""" % clsname), locals())
+    
+# NOTE: most assertion expressions were generated, then formatted
+# by PyTidy, hence the dense formatting.
+
+class LexerTest(TemplateTest):
+    
+    def _compare(self, node, expected):
+        eq_(repr(node), repr(expected))
+    
+    def test_text_and_tag(self):
+        template = """
+<b>Hello world</b>
+        <%def name="foo()">
+                this is a def.
+        </%def>
+        
+        and some more text.
+"""
+        node = Lexer(template).parse()
+        self._compare(node, TemplateNode({},
+                      [Text('''\n<b>Hello world</b>\n        ''', (1,
+                      1)), DefTag('def', {'name': 'foo()'}, (3, 9),
+                      [Text('''\n                this is a def.\n        ''',
+                      (3, 28))]),
+                      Text('''\n        \n        and some more text.\n''',
+                      (5, 16))]))
+
+    def test_unclosed_tag(self):
+        template = """
+        
+            <%def name="foo()">
+             other text
+        """
+        try:
+            nodes = Lexer(template).parse()
+            assert False
+        except exceptions.SyntaxException as e:
+            assert str(e) == "Unclosed tag: <%def> at line: 5 char: 9"
+
+    def test_onlyclosed_tag(self):
+        template = \
+            """
+            <%def name="foo()">
+                foo
+            </%def>
+            
+            </%namespace>
+            
+            hi.
+        """
+        self.assertRaises(exceptions.SyntaxException,
+                          Lexer(template).parse)
+    
+    def test_noexpr_allowed(self):
+        template = \
+            """
+            <%namespace name="${foo}"/>
+        """
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+
+    def test_unmatched_tag(self):
+        template = \
+            """
+        <%namespace name="bar">
+        <%def name="foo()">
+            foo
+            </%namespace>
+        </%def>
+        
+        
+        hi.
+"""
+        self.assertRaises(exceptions.SyntaxException,
+                          Lexer(template).parse)
+
+    def test_nonexistent_tag(self):
+        template = """
+            <%lala x="5"/>
+        """
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+
+    def test_wrongcase_tag(self):
+        template = \
+            """
+            <%DEF name="foo()">
+            </%def>
+        
+        """
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+    
+    def test_percent_escape(self):
+        template = \
+            """
+        
+%% some whatever.
+
+    %% more some whatever
+    % if foo:
+    % endif
+        """
+        node = Lexer(template).parse()
+        self._compare(node, TemplateNode({}, [Text('''\n        \n''',
+                      (1, 1)), Text('''% some whatever.\n\n''', (3, 2)),
+                      Text('   %% more some whatever\n', (5, 2)),
+                      ControlLine('if', 'if foo:', False, (6, 1)),
+                      ControlLine('if', 'endif', True, (7, 1)),
+                      Text('        ', (8, 1))]))
+        
+    def test_text_tag(self):
+        template = \
+            """
+        ## comment
+        % if foo:
+            hi
+        % endif
+        <%text>
+            # more code
+            
+            % more code
+            <%illegal compionent>/></>
+            <%def name="laal()">def</%def>
+            
+            
+        </%text>
+
+        <%def name="foo()">this is foo</%def>
+        
+        % if bar:
+            code
+        % endif
+        """
+        node = Lexer(template).parse()
+        self._compare(node, 
+            TemplateNode({}, [Text('\n', (1, 1)),
+              Comment('comment', (2, 1)), 
+              ControlLine('if', 'if foo:', False, (3, 1)),
+              Text('            hi\n', (4, 1)),
+              ControlLine('if', 'endif', True, (5, 1)),
+              Text('        ', (6, 1)), TextTag('text', {},
+              (6, 9),
+              [Text('''\n            # more code\n            '''
+              '''\n            % more code\n            '''
+              '''<%illegal compionent>/></>\n            '''
+              '''<%def name="laal()">def</%def>\n       '''
+              '''     \n            \n        ''',
+                      (6, 16))]), Text('''
+
+        ''', (14, 17)),
+                      DefTag('def', {'name': 'foo()'}, (16, 9),
+                      [Text('this is foo', (16, 28))]),
+                      Text('''\n        \n''', (16, 46)),
+                      ControlLine('if', 'if bar:', False, (18, 1)),
+                      Text('            code\n', (19, 1)),
+                      ControlLine('if', 'endif', True, (20, 1)),
+                      Text('        ', (21, 1))]))
+
+    def test_def_syntax(self):
+        template = \
+            """
+        <%def lala>
+            hi
+        </%def>
+"""
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+    
+    def test_def_syntax_2(self):
+        template = \
+            """
+        <%def name="lala">
+            hi
+        </%def>
+    """
+        self.assertRaises(exceptions.CompileException,
+                          Lexer(template).parse)
+
+    def test_whitespace_equals(self):
+        template = \
+            """
+            <%def name = "adef()" >
+              adef
+            </%def>
+        """
+        node = Lexer(template).parse()
+        self._compare(node, TemplateNode({}, [Text('\n            ',
+                      (1, 1)), DefTag('def', {'name': 'adef()'}, (2,
+                      13),
+                      [Text('''\n              adef\n            ''',
+                      (2, 36))]), Text('\n        ', (4, 20))]))
+
+    def test_ns_tag_closed(self):
+        template = \
+            """
+        
+            <%self:go x="1" y="2" z="${'hi' + ' ' + 'there'}"/>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''
+        
+            ''', (1, 1)),
+                      CallNamespaceTag('self:go', {'x': '1', 'y'
+                      : '2', 'z': "${'hi' + ' ' + 'there'}"}, (3,
+                      13), []), Text('\n        ', (3, 64))]))
+    
+    def test_ns_tag_empty(self):
+        template = \
+            """
+            <%form:option value=""></%form:option>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n            ',
+                      (1, 1)), CallNamespaceTag('form:option',
+                      {'value': ''}, (2, 13), []), Text('\n        '
+                      , (2, 51))]))
+
+    def test_ns_tag_open(self):
+        template = \
+            """
+        
+            <%self:go x="1" y="${process()}">
+                this is the body
+            </%self:go>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''
+        
+            ''', (1, 1)),
+                      CallNamespaceTag('self:go', {'x': '1', 'y'
+                      : '${process()}'}, (3, 13),
+                      [Text('''
+                this is the body
+            ''',
+                      (3, 46))]), Text('\n        ', (5, 24))]))
+        
+    def test_expr_in_attribute(self):
+        """test some slightly trickier expressions.
+        
+        you can still trip up the expression parsing, though, unless we
+        integrated really deeply somehow with AST."""
+
+        template = \
+            """
+            <%call expr="foo>bar and 'lala' or 'hoho'"/>
+            <%call expr='foo<bar and hoho>lala and "x" + "y"'/>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n            ',
+                      (1, 1)), CallTag('call', {'expr'
+                      : "foo>bar and 'lala' or 'hoho'"}, (2, 13), []),
+                      Text('\n            ', (2, 57)), CallTag('call'
+                      , {'expr': 'foo<bar and hoho>lala and "x" + "y"'
+                      }, (3, 13), []), Text('\n        ', (3, 64))]))
+
+    def test_pagetag(self):
+        template = \
+            """
+            <%page cached="True", args="a, b"/>
+            
+            some template
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n            ',
+                      (1, 1)), PageTag('page', {'args': 'a, b',
+                      'cached': 'True'}, (2, 13), []),
+                      Text('''
+            
+            some template
+        ''',
+                      (2, 48))]))
+
+    def test_nesting(self):
+        template = \
+            """
+        
+        <%namespace name="ns">
+            <%def name="lala(hi, there)">
+                <%call expr="something()"/>
+            </%def>
+        </%namespace>
+        
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''
+        
+        ''', (1, 1)),
+                      NamespaceTag('namespace', {'name': 'ns'}, (3,
+                      9), [Text('\n            ', (3, 31)),
+                      DefTag('def', {'name': 'lala(hi, there)'}, (4,
+                      13), [Text('\n                ', (4, 42)),
+                      CallTag('call', {'expr': 'something()'}, (5,
+                      17), []), Text('\n            ', (5, 44))]),
+                      Text('\n        ', (6, 20))]),
+                      Text('''
+        
+        ''', (7, 22))]))
+
+    if util.py3k:
+        def test_code(self):
+            template = \
+"""text
+    <%
+        print("hi")
+        for x in range(1,5):
+            print x
+    %>
+more text
+    <%!
+        import foo
+    %>
+"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, 
+            TemplateNode({}, [
+                Text('text\n    ', (1, 1)), 
+                Code('\nprint("hi")\nfor x in range(1,5):\n    '
+                            'print x\n    \n', False, (2, 5)), 
+                Text('\nmore text\n    ', (6, 7)), 
+                Code('\nimport foo\n    \n', True, (8, 5)), 
+                Text('\n', (10, 7))])
+            )
+
+
+    else:
+
+        def test_code(self):
+            template = \
+"""text
+    <%
+        print "hi"
+        for x in range(1,5):
+            print x
+    %>
+more text
+    <%!
+        import foo
+    %>
+"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, 
+            TemplateNode({}, [
+                Text('text\n    ', (1, 1)), 
+                Code('\nprint "hi"\nfor x in range(1,5):\n    '
+                            'print x\n    \n', False, (2, 5)), 
+                Text('\nmore text\n    ', (6, 7)), 
+                Code('\nimport foo\n    \n', True, (8, 5)), 
+                Text('\n', (10, 7))])
+            )
+    
+    def test_code_and_tags(self):
+        template = \
+            """
+<%namespace name="foo">
+    <%def name="x()">
+        this is x
+    </%def>
+    <%def name="y()">
+        this is y
+    </%def>
+</%namespace>
+
+<%
+    result = []
+    data = get_data()
+    for x in data:
+        result.append(x+7)
+%>
+
+    result: <%call expr="foo.x(result)"/>
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)),
+                      NamespaceTag('namespace', {'name': 'foo'}, (2,
+                      1), [Text('\n    ', (2, 24)), DefTag('def',
+                      {'name': 'x()'}, (3, 5),
+                      [Text('''\n        this is x\n    ''', (3, 22))]),
+                      Text('\n    ', (5, 12)), DefTag('def', {'name'
+                      : 'y()'}, (6, 5),
+                      [Text('''\n        this is y\n    ''', (6, 22))]),
+                      Text('\n', (8, 12))]), Text('''\n\n''', (9, 14)),
+                      Code('''\nresult = []\ndata = get_data()\n'''
+                      '''for x in data:\n    result.append(x+7)\n\n''',
+                      False, (11, 1)), Text('''\n\n    result: ''', (16,
+                      3)), CallTag('call', {'expr': 'foo.x(result)'
+                      }, (18, 13), []), Text('\n', (18, 42))]))
+
+    def test_expression(self):
+        template = \
+            """
+        this is some ${text} and this is ${textwith | escapes, moreescapes}
+        <%def name="hi()">
+            give me ${foo()} and ${bar()}
+        </%def>
+        ${hi()}
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('\n        this is some ', (1, 1)),
+                      Expression('text', [], (2, 22)),
+                      Text(' and this is ', (2, 29)),
+                      Expression('textwith ', ['escapes', 'moreescapes'
+                      ], (2, 42)), Text('\n        ', (2, 76)),
+                      DefTag('def', {'name': 'hi()'}, (3, 9),
+                      [Text('\n            give me ', (3, 27)),
+                      Expression('foo()', [], (4, 21)), Text(' and ',
+                      (4, 29)), Expression('bar()', [], (4, 34)),
+                      Text('\n        ', (4, 42))]), Text('\n        '
+                      , (5, 16)), Expression('hi()', [], (6, 9)),
+                      Text('\n', (6, 16))]))
+        
+
+    def test_tricky_expression(self):
+        template = """
+        
+            ${x and "|" or "hi"}
+        """
+        nodes = Lexer(template).parse()
+        self._compare(
+            nodes,
+            TemplateNode({}, [
+                Text('\n        \n            ', (1, 1)), 
+                Expression('x and "|" or "hi"', [], (3, 13)), 
+                Text('\n        ', (3, 33))
+            ])
+        )
+
+        template = """
+        
+            ${hello + '''heres '{|}' text | | }''' | escape1}
+        """
+        nodes = Lexer(template).parse()
+        self._compare(
+            nodes,
+            TemplateNode({}, [
+                Text('\n        \n            ', (1, 1)), 
+                Expression("hello + '''heres '{|}' text | | }''' ", 
+                                ['escape1'], (3, 13)), 
+                Text('\n        ', (3, 62))
+            ])
+        )
+
+    def test_tricky_code(self):
+        if util.py3k:
+            template = """<% print('hi %>') %>"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, TemplateNode({},
+                          [Code("print('hi %>') \n", False, (1, 1))]))
+        else:
+            template = """<% print 'hi %>' %>"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, TemplateNode({},
+                          [Code("print 'hi %>' \n", False, (1, 1))]))
+
+    def test_tricky_code_2(self):
+        template = \
+            """<% 
+        # someone's comment
+        %>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Code(""" 
+        # someone's comment
+        
+""",
+                      False, (1, 1)), Text('\n        ', (3, 11))]))
+
+    if util.py3k:
+        def test_tricky_code_3(self):
+            template = \
+                """<%
+            print('hi')
+            # this is a comment
+            # another comment
+            x = 7 # someone's '''comment
+            print('''
+        there
+        ''')
+            # someone else's comment
+        %> '''and now some text '''"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, TemplateNode({},
+                          [Code("""
+print('hi')
+# this is a comment
+# another comment
+x = 7 # someone's '''comment
+print('''
+        there
+        ''')
+# someone else's comment
+        
+""",
+                          False, (1, 1)),
+                          Text(" '''and now some text '''", (10,
+                          11))]))
+    else:
+        def test_tricky_code_3(self):
+            template = \
+                """<%
+            print 'hi'
+            # this is a comment
+            # another comment
+            x = 7 # someone's '''comment
+            print '''
+        there
+        '''
+            # someone else's comment
+        %> '''and now some text '''"""
+            nodes = Lexer(template).parse()
+            self._compare(nodes, TemplateNode({},
+                      [Code("""\nprint 'hi'\n# this is a comment\n"""
+                      """# another comment\nx = 7 """
+                      """# someone's '''comment\nprint '''\n        """
+                      """there\n        '''\n# someone else's """
+                      """comment\n        \n""",
+                      False, (1, 1)),
+                      Text(" '''and now some text '''", (10,11))]))
+        
+    def test_control_lines(self):
+        template = \
+            """
+text text la la
+% if foo():
+ mroe text la la blah blah
+% endif
+
+        and osme more stuff
+        % for l in range(1,5):
+    tex tesl asdl l is ${l} kfmas d
+      % endfor
+    tetx text
+    
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''\ntext text la la\n''', (1, 1)),
+                      ControlLine('if', 'if foo():', False, (3, 1)),
+                      Text(' mroe text la la blah blah\n', (4, 1)),
+                      ControlLine('if', 'endif', True, (5, 1)),
+                      Text('''\n        and osme more stuff\n''', (6,
+                      1)), ControlLine('for', 'for l in range(1,5):',
+                      False, (8, 1)), Text('    tex tesl asdl l is ',
+                      (9, 1)), Expression('l', [], (9, 24)),
+                      Text(' kfmas d\n', (9, 28)), ControlLine('for',
+                      'endfor', True, (10, 1)),
+                      Text('''    tetx text\n    \n''', (11, 1))]))
+
+    def test_control_lines_2(self):
+        template = \
+"""% for file in requestattr['toc'].filenames:
+    x
+% endfor
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [ControlLine('for',
+                      "for file in requestattr['toc'].filenames:",
+                      False, (1, 1)), Text('    x\n', (2, 1)),
+                      ControlLine('for', 'endfor', True, (3, 1))]))
+
+    def test_long_control_lines(self):
+        template = \
+        """
+    % for file in \\
+        requestattr['toc'].filenames:
+        x
+    % endfor
+        """
+        nodes = Lexer(template).parse()
+        self._compare(
+            nodes,
+            TemplateNode({}, [
+                Text('\n', (1, 1)), 
+                ControlLine('for', "for file in \\\n        "
+                                "requestattr['toc'].filenames:", 
+                                False, (2, 1)), 
+                Text('        x\n', (4, 1)), 
+                ControlLine('for', 'endfor', True, (5, 1)), 
+                Text('        ', (6, 1))
+            ])
+        )
+
+    def test_unmatched_control(self):
+        template = """
+
+        % if foo:
+            % for x in range(1,5):
+        % endif
+"""
+        assert_raises_message(
+            exceptions.SyntaxException,
+            "Keyword 'endif' doesn't match keyword 'for' at line: 5 char: 1",
+            Lexer(template).parse
+        )
+
+    def test_unmatched_control_2(self):
+        template = """
+
+        % if foo:
+            % for x in range(1,5):
+            % endfor
+"""
+
+        assert_raises_message(
+            exceptions.SyntaxException,
+            "Unterminated control keyword: 'if' at line: 3 char: 1",
+            Lexer(template).parse
+        )
+
+    def test_unmatched_control_3(self):
+        template = """
+
+        % if foo:
+            % for x in range(1,5):
+            % endlala
+        % endif
+"""
+        assert_raises_message(
+            exceptions.SyntaxException,
+            "Keyword 'endlala' doesn't match keyword 'for' at line: 5 char: 1",
+            Lexer(template).parse
+        )
+    
+    def test_ternary_control(self):
+        template = \
+            """
+        % if x:
+            hi
+        % elif y+7==10:
+            there
+        % elif lala:
+            lala
+        % else:
+            hi
+        % endif
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)),
+                      ControlLine('if', 'if x:', False, (2, 1)),
+                      Text('            hi\n', (3, 1)),
+                      ControlLine('elif', 'elif y+7==10:', False, (4,
+                      1)), Text('            there\n', (5, 1)),
+                      ControlLine('elif', 'elif lala:', False, (6,
+                      1)), Text('            lala\n', (7, 1)),
+                      ControlLine('else', 'else:', False, (8, 1)),
+                      Text('            hi\n', (9, 1)),
+                      ControlLine('if', 'endif', True, (10, 1))]))
+        
+    def test_integration(self):
+        template = \
+            """<%namespace name="foo" file="somefile.html"/>
+ ## inherit from foobar.html
+<%inherit file="foobar.html"/>
+
+<%def name="header()">
+     <div>header</div>
+</%def>
+<%def name="footer()">
+    <div> footer</div>
+</%def>
+
+<table>
+    % for j in data():
+    <tr>
+        % for x in j:
+            <td>Hello ${x| h}</td>
+        % endfor
+    </tr>
+    % endfor
+</table>
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [NamespaceTag('namespace'
+                      , {'file': 'somefile.html', 'name': 'foo'},
+                      (1, 1), []), Text('\n', (1, 46)),
+                      Comment('inherit from foobar.html', (2, 1)),
+                      InheritTag('inherit', {'file': 'foobar.html'},
+                      (3, 1), []), Text('''\n\n''', (3, 31)),
+                      DefTag('def', {'name': 'header()'}, (5, 1),
+                      [Text('''\n     <div>header</div>\n''', (5,
+                      23))]), Text('\n', (7, 8)), DefTag('def',
+                      {'name': 'footer()'}, (8, 1),
+                      [Text('''\n    <div> footer</div>\n''', (8,
+                      23))]), Text('''\n\n<table>\n''', (10, 8)),
+                      ControlLine('for', 'for j in data():', False,
+                      (13, 1)), Text('    <tr>\n', (14, 1)),
+                      ControlLine('for', 'for x in j:', False, (15,
+                      1)), Text('            <td>Hello ', (16, 1)),
+                      Expression('x', ['h'], (16, 23)), Text('</td>\n'
+                      , (16, 30)), ControlLine('for', 'endfor', True,
+                      (17, 1)), Text('    </tr>\n', (18, 1)),
+                      ControlLine('for', 'endfor', True, (19, 1)),
+                      Text('</table>\n', (20, 1))]))
+        
+    def test_comment_after_statement(self):
+        template = \
+            """
+        % if x: #comment
+            hi
+        % else: #next
+            hi
+        % endif #end
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({}, [Text('\n', (1, 1)),
+                      ControlLine('if', 'if x: #comment', False, (2,
+                      1)), Text('            hi\n', (3, 1)),
+                      ControlLine('else', 'else: #next', False, (4,
+                      1)), Text('            hi\n', (5, 1)),
+                      ControlLine('if', 'endif #end', True, (6, 1))]))
+
+    def test_crlf(self):
+        template = open(self._file_path("crlf.html"), 'rb').read()
+        nodes = Lexer(template).parse()
+        self._compare(
+            nodes,
+            TemplateNode({}, [
+                Text('<html>\r\n\r\n', (1, 1)), 
+                PageTag('page', {
+                            'args': "a=['foo',\n                'bar']"
+                        }, (3, 1), []), 
+                Text('\r\n\r\nlike the name says.\r\n\r\n', (4, 26)), 
+                ControlLine('for', 'for x in [1,2,3]:', False, (8, 1)), 
+                Text('        ', (9, 1)), 
+                Expression('x', [], (9, 9)), 
+                ControlLine('for', 'endfor', True, (10, 1)), 
+                Text('\r\n', (11, 1)), 
+                Expression("trumpeter == 'Miles' and "
+                                "trumpeter or \\\n      'Dizzy'", 
+                                [], (12, 1)), 
+                Text('\r\n\r\n', (13, 15)), 
+                DefTag('def', {'name': 'hi()'}, (15, 1), [
+                    Text('\r\n    hi!\r\n', (15, 19))]), 
+                    Text('\r\n\r\n</html>\r\n', (17, 8))
+                ])
+        )
+        assert flatten_result(Template(template).render()) \
+            == """<html> like the name says. 1 2 3 Dizzy </html>"""
+    
+    def test_comments(self):
+        template = \
+            """
+<style>
+ #someselector
+ # other non comment stuff
+</style>
+## a comment
+
+# also not a comment
+
+   ## this is a comment
+   
+this is ## not a comment
+
+<%doc> multiline
+comment
+</%doc>
+
+hi
+"""
+        nodes = Lexer(template).parse()
+        self._compare(nodes, TemplateNode({},
+                      [Text('''\n<style>\n #someselector\n # '''
+                        '''other non comment stuff\n</style>\n''',
+                      (1, 1)), Comment('a comment', (6, 1)),
+                      Text('''\n# also not a comment\n\n''', (7, 1)),
+                      Comment('this is a comment', (10, 1)),
+                      Text('''   \nthis is ## not a comment\n\n''', (11,
+                      1)), Comment(''' multiline\ncomment\n''', (14,
+                      1)), Text('''
+
+hi
+''', (16, 8))]))
+    
+    def test_docs(self):
+        template = \
+            """
+        <%doc>
+            this is a comment
+        </%doc>
+        <%def name="foo()">
+            <%doc>
+                this is the foo func
+            </%doc>
+        </%def>
+        """
+        nodes = Lexer(template).parse()
+        self._compare(nodes, 
+            TemplateNode({}, [Text('\n        ', (1,
+              1)),
+              Comment('''\n            this is a comment\n        ''',
+              (2, 9)), Text('\n        ', (4, 16)),
+              DefTag('def', {'name': 'foo()'}, (5, 9),
+              [Text('\n            ', (5, 28)),
+              Comment('''\n                this is the foo func\n'''
+                '''            ''',
+              (6, 13)), Text('\n        ', (8, 20))]),
+              Text('\n        ', (9, 16))]))
+
+    def test_preprocess(self):
+
+        def preproc(text):
+            return re.sub(r'(?<=\n)\s*#[^#]', '##', text)
+
+        template = \
+            """
+    hi
+    # old style comment
+# another comment
+"""
+        nodes = Lexer(template, preprocessor=preproc).parse()
+        self._compare(nodes, TemplateNode({}, [Text('''\n    hi\n''',
+                      (1, 1)), Comment('old style comment', (3, 1)),
+                      Comment('another comment', (4, 1))]))
diff --git a/lib3/mako-0.3.6/test/test_lookup.py b/lib3/mako-0.3.6/test/test_lookup.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_lookup.py
@@ -0,0 +1,65 @@
+from mako.template import Template
+from mako import lookup, exceptions
+from .util import flatten_result, result_lines
+import unittest
+
+from test import TemplateTest, template_base, module_base
+
+tl = lookup.TemplateLookup(directories=[template_base])
+class LookupTest(unittest.TestCase):
+    def test_basic(self):
+        t = tl.get_template('index.html')
+        assert result_lines(t.render()) == [
+            "this is index"
+        ]
+    def test_subdir(self):
+        t = tl.get_template('/subdir/index.html')
+        assert result_lines(t.render()) == [
+            "this is sub index",
+            "this is include 2"
+
+        ]
+
+        assert tl.get_template('/subdir/index.html').module_id \
+                            == '_subdir_index_html'
+    
+    def test_updir(self):
+        t = tl.get_template('/subdir/foo/../bar/../index.html')
+        assert result_lines(t.render()) == [
+            "this is sub index",
+            "this is include 2"
+
+        ]
+    
+    def test_directory_lookup(self):
+        """test that hitting an existent directory still raises
+        LookupError."""
+        
+        self.assertRaises(exceptions.TopLevelLookupException,
+            tl.get_template, "/subdir"
+        )
+        
+    def test_no_lookup(self):
+        t = Template("hi <%include file='foo.html'/>")
+        try:
+            t.render()
+            assert False
+        except exceptions.TemplateLookupException as e:
+            assert str(e) == \
+                "Template 'memory:%s' has no TemplateLookup associated" % \
+                hex(id(t))
+            
+    def test_uri_adjust(self):
+        tl = lookup.TemplateLookup(directories=['/foo/bar'])
+        assert tl.filename_to_uri('/foo/bar/etc/lala/index.html') == \
+                        '/etc/lala/index.html'
+
+        tl = lookup.TemplateLookup(directories=['./foo/bar'])
+        assert tl.filename_to_uri('./foo/bar/etc/index.html') == \
+                        '/etc/index.html'
+    
+    def test_uri_cache(self):
+        """test that the _uri_cache dictionary is available"""
+        tl._uri_cache[('foo', 'bar')] = '/some/path'
+        assert tl._uri_cache[('foo', 'bar')] == '/some/path'
+        
diff --git a/lib3/mako-0.3.6/test/test_lru.py b/lib3/mako-0.3.6/test/test_lru.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_lru.py
@@ -0,0 +1,111 @@
+from mako.util import LRUCache
+import string, unittest, time, random
+
+import _thread
+
+class item:
+    def __init__(self, id):
+        self.id = id
+
+    def __str__(self):
+        return "item id %d" % self.id
+
+class LRUTest(unittest.TestCase):
+
+
+    def testlru(self):                
+        l = LRUCache(10, threshold=.2)
+        
+        for id in range(1,20):
+            l[id] = item(id)
+        
+        # first couple of items should be gone
+        self.assert_(1 not in l)    
+        self.assert_(2 not in l)
+        
+        # next batch over the threshold of 10 should be present
+        for id in range(11,20):
+            self.assert_(id in l)
+
+        l[12]
+        l[15]
+        l[23] = item(23)
+        l[24] = item(24)
+        l[25] = item(25)
+        l[26] = item(26)
+        l[27] = item(27)
+
+        self.assert_(11 not in l)
+        self.assert_(13 not in l)
+        
+        for id in (25, 24, 23, 14, 12, 19, 18, 17, 16, 15):
+            self.assert_(id in l)    
+
+    def _disabled_test_threaded(self):
+        size = 100
+        threshold = .5
+        all_elems = 2000
+        hot_zone = list(range(30,40))
+        cache = LRUCache(size, threshold)
+        
+        # element to store
+        class Element(object):
+            def __init__(self, id):
+                self.id = id
+                self.regets = 0
+                
+        # return an element.  we will favor ids in the relatively small
+        # "hot zone" 25% of  the time.
+        def get_elem():
+            if random.randint(1,4) == 1:
+                return hot_zone[random.randint(0, len(hot_zone) - 1)]
+            else:
+                return random.randint(1, all_elems)
+        
+        total = [0]
+        # request thread.
+        def request_elem():
+            while True:
+                total[0] += 1
+                id = get_elem()
+                try:
+                    elem = cache[id]
+                    elem.regets += 1
+                except KeyError:
+                    e = Element(id)
+                    cache[id] = e
+                    
+                time.sleep(random.random() / 1000)
+
+        for x in range(0,20):
+            _thread.start_new_thread(request_elem, ())
+        
+        # assert size doesn't grow unbounded, doesnt shrink well below size
+        for x in range(0,5):
+            time.sleep(1)
+            print("size:", len(cache))
+            assert len(cache) < size + size * threshold * 2
+            assert len(cache) > size - (size * .1)
+        
+        # computs the average number of times a range of elements were "reused",
+        # i.e. without being removed from the cache.
+        def average_regets_in_range(start, end):
+            elem = [e for e in list(cache.values()) if e.id >= start and e.id <= end]
+            if len(elem) == 0:
+                return 0
+            avg = sum([e.regets for e in elem]) / len(elem)
+            return avg
+
+        hotzone_avg = average_regets_in_range(30, 40)
+        control_avg = average_regets_in_range(450,760)
+        total_avg = average_regets_in_range(0, 2000)
+        
+        # hotzone should be way above the others
+        print("total fetches", total[0], "hotzone", \
+                                hotzone_avg, "control", \
+                                control_avg, "total", total_avg)
+        
+        assert hotzone_avg > total_avg * 5 > control_avg * 5
+        
+        
+
diff --git a/lib3/mako-0.3.6/test/test_namespace.py b/lib3/mako-0.3.6/test/test_namespace.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_namespace.py
@@ -0,0 +1,792 @@
+from mako.template import Template
+from mako import lookup
+from .util import flatten_result, result_lines
+from test import TemplateTest, eq_
+
+class NamespaceTest(TemplateTest):
+    def test_inline_crossreference(self):
+        self._do_memory_test(
+            """
+            <%namespace name="x">
+                <%def name="a()">
+                    this is x a
+                </%def>
+                <%def name="b()">
+                    this is x b, and heres ${a()}
+                </%def>
+            </%namespace>
+        
+            ${x.a()}
+        
+            ${x.b()}
+    """,
+            "this is x a this is x b, and heres this is x a",
+            filters=flatten_result
+        )
+
+    def test_inline_assignment(self):
+        self._do_memory_test(
+            """
+            <%namespace name="x">
+                <%def name="a()">
+                    <%
+                        x = 5
+                    %>
+                    this is x: ${x}
+                </%def>
+            </%namespace>
+
+            ${x.a()}
+
+    """,
+            "this is x: 5",
+            filters=flatten_result
+        )
+
+    def test_inline_arguments(self):
+        self._do_memory_test(
+            """
+            <%namespace name="x">
+                <%def name="a(x, y)">
+                    <%
+                        result = x * y
+                    %>
+                    result: ${result}
+                </%def>
+            </%namespace>
+
+            ${x.a(5, 10)}
+
+    """,
+            "result: 50",
+            filters=flatten_result
+        )
+
+    def test_inline_not_duped(self):
+        self._do_memory_test(
+            """
+            <%namespace name="x">
+                <%def name="a()">
+                    foo
+                </%def>
+            </%namespace>
+
+            <%
+                assert x.a is not UNDEFINED, "namespace x.a wasn't defined"
+                assert a is UNDEFINED, "name 'a' is in the body locals"
+            %>
+
+    """,
+            "",
+            filters=flatten_result
+        )
+
+    def test_dynamic(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('a', """
+        <%namespace name="b" file="${context['b_def']}"/>
+
+        a.  b: ${b.body()}
+""")
+
+        collection.put_string('b', """
+        b.
+""")
+
+        eq_(
+            flatten_result(collection.get_template('a').render(b_def='b')),
+            "a. b: b."
+        )
+        
+    def test_template(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" file="defs.html"/>
+        
+        this is main.  ${comp.def1("hi")}
+        ${comp.def2("there")}
+""")
+
+        collection.put_string('defs.html', """
+        <%def name="def1(s)">
+            def1: ${s}
+        </%def>
+        
+        <%def name="def2(x)">
+            def2: ${x}
+        </%def>
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. def1: hi def2: there"
+    
+    def test_module(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" module="test.sample_module_namespace"/>
+
+        this is main.  ${comp.foo1()}
+        ${comp.foo2("hi")}
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+
+    def test_module_2(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" module="test.foo.test_ns"/>
+
+        this is main.  ${comp.foo1()}
+        ${comp.foo2("hi")}
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+
+    def test_module_imports(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace import="*" module="test.foo.test_ns"/>
+
+        this is main.  ${foo1()}
+        ${foo2("hi")}
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+
+    def test_module_imports_2(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace import="foo1, foo2" module="test.foo.test_ns"/>
+
+        this is main.  ${foo1()}
+        ${foo2("hi")}
+""")
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. this is foo1. this is foo2, x is hi"
+        
+    def test_context(self):
+        """test that namespace callables get access to the current context"""
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" file="defs.html"/>
+
+        this is main.  ${comp.def1()}
+        ${comp.def2("there")}
+""")
+
+        collection.put_string('defs.html', """
+        <%def name="def1()">
+            def1: x is ${x}
+        </%def>
+
+        <%def name="def2(x)">
+            def2: x is ${x}
+        </%def>
+""")
+
+        assert flatten_result(collection.get_template('main.html').render(x="context x")) == "this is main. def1: x is context x def2: x is there"
+        
+    def test_overload(self):
+        collection = lookup.TemplateLookup()
+
+        collection.put_string('main.html', """
+        <%namespace name="comp" file="defs.html">
+            <%def name="def1(x, y)">
+                overridden def1 ${x}, ${y}
+            </%def>
+        </%namespace>
+
+        this is main.  ${comp.def1("hi", "there")}
+        ${comp.def2("there")}
+    """)
+
+        collection.put_string('defs.html', """
+        <%def name="def1(s)">
+            def1: ${s}
+        </%def>
+
+        <%def name="def2(x)">
+            def2: ${x}
+        </%def>
+    """)
+
+        assert flatten_result(collection.get_template('main.html').render()) == "this is main. overridden def1 hi, there def2: there"
+
+    def test_getattr(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("main.html", """
+            <%namespace name="foo" file="ns.html"/>
+            <%
+                 if hasattr(foo, 'lala'):
+                     foo.lala()
+                 if not hasattr(foo, 'hoho'):
+                     context.write('foo has no hoho.')
+            %>
+         """)
+        collection.put_string("ns.html", """
+          <%def name="lala()">this is lala.</%def>
+        """)
+        assert flatten_result(collection.get_template("main.html").render()) == "this is lala.foo has no hoho."
+
+    def test_in_def(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("main.html", """
+            <%namespace name="foo" file="ns.html"/>
+            
+            this is main.  ${bar()}
+            <%def name="bar()">
+                this is bar, foo is ${foo.bar()}
+            </%def>
+        """)
+        
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+            </%def>
+        """)
+
+        assert result_lines(collection.get_template("main.html").render()) == [
+            "this is main.",
+            "this is bar, foo is" ,
+            "this is ns.html->bar"
+        ]
+
+
+    def test_in_remote_def(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("main.html", """
+            <%namespace name="foo" file="ns.html"/>
+
+            this is main.  ${bar()}
+            <%def name="bar()">
+                this is bar, foo is ${foo.bar()}
+            </%def>
+        """)
+
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+            </%def>
+        """)
+        
+        collection.put_string("index.html", """
+            <%namespace name="main" file="main.html"/>
+            
+            this is index
+            ${main.bar()}
+        """)
+
+        assert result_lines(collection.get_template("index.html").render()) == [  
+            "this is index",
+            "this is bar, foo is" ,
+            "this is ns.html->bar"
+        ]
+    
+    def test_dont_pollute_self(self):
+        # test that get_namespace() doesn't modify the original context
+        # incompatibly
+        
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+
+        <%def name="foo()">
+        <%
+            foo = local.get_namespace("foo.html")
+        %>
+        </%def>
+
+        name: ${self.name}
+        name via bar: ${bar()}
+
+        ${next.body()}
+
+        name: ${self.name}
+        name via bar: ${bar()}
+        <%def name="bar()">
+            ${self.name}
+        </%def>
+
+
+        """)
+
+        collection.put_string("page.html", """
+        <%inherit file="base.html"/>
+
+        ${self.foo()}
+
+        hello world
+
+        """)
+
+        collection.put_string("foo.html", """<%inherit file="base.html"/>""")
+        assert result_lines(collection.get_template("page.html").render()) == [
+            "name: self:page.html",
+            "name via bar:",
+            "self:page.html",
+            "hello world",
+            "name: self:page.html",
+            "name via bar:",
+            "self:page.html"
+        ]
+        
+    def test_inheritance(self):
+        """test namespace initialization in a base inherited template that doesnt otherwise access the namespace"""
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%namespace name="foo" file="ns.html" inheritable="True"/>
+            
+            ${next.body()}
+""")
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+            </%def>
+        """)
+
+        collection.put_string("index.html", """
+            <%inherit file="base.html"/>
+    
+            this is index
+            ${self.foo.bar()}
+        """)
+        
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is index",
+            "this is ns.html->bar"
+        ]
+
+    def test_inheritance_two(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%def name="foo()">
+                base.foo
+            </%def>
+            
+            <%def name="bat()">
+                base.bat
+            </%def>
+""")
+        collection.put_string("lib.html", """
+            <%inherit file="base.html"/>
+            <%def name="bar()">
+                lib.bar
+                ${parent.foo()}
+                ${self.foo()}
+                ${parent.bat()}
+                ${self.bat()}
+            </%def>
+            
+            <%def name="foo()">
+                lib.foo
+            </%def>
+                
+        """)
+
+        collection.put_string("front.html", """
+            <%namespace name="lib" file="lib.html"/>
+            ${lib.bar()}
+        """)
+
+        assert result_lines(collection.get_template("front.html").render()) == ['lib.bar', 'base.foo', 'lib.foo', 'base.bat', 'base.bat']
+
+    def test_attr(self):
+        l = lookup.TemplateLookup()
+
+        l.put_string("foo.html", """
+        <%!
+            foofoo = "foo foo"
+            onlyfoo = "only foo"
+        %>
+        <%inherit file="base.html"/>
+        <%def name="setup()">
+            <%
+            self.attr.foolala = "foo lala"
+            %>
+        </%def>
+        ${self.attr.basefoo}
+        ${self.attr.foofoo}
+        ${self.attr.onlyfoo}
+        ${self.attr.lala}
+        ${self.attr.foolala}
+        """)
+
+        l.put_string("base.html", """
+        <%!
+            basefoo = "base foo 1"
+            foofoo = "base foo 2"
+        %>
+        <%
+            self.attr.lala = "base lala"
+        %>
+        
+        ${self.attr.basefoo}
+        ${self.attr.foofoo}
+        ${self.attr.onlyfoo}
+        ${self.attr.lala}
+        ${self.setup()}
+        ${self.attr.foolala}
+        body
+        ${self.body()}
+        """)
+
+        assert result_lines(l.get_template("foo.html").render()) == [
+            "base foo 1",
+            "foo foo",
+            "only foo",
+            "base lala",
+            "foo lala",
+            "body",
+            "base foo 1",
+            "foo foo",
+            "only foo",
+            "base lala",
+            "foo lala",
+        ]
+    
+    def test_attr_raise(self):
+        l = lookup.TemplateLookup()
+
+        l.put_string("foo.html", """
+            <%def name="foo()">
+            </%def>
+        """)
+
+        l.put_string("bar.html", """
+        <%namespace name="foo" file="foo.html"/>
+        
+        ${foo.notfoo()}
+        """)
+
+        self.assertRaises(AttributeError, l.get_template("bar.html").render)
+        
+    def test_custom_tag_1(self):
+        template = Template("""
+        
+            <%def name="foo(x, y)">
+                foo: ${x} ${y}
+            </%def>
+            
+            <%self:foo x="5" y="${7+8}"/>
+        """)
+        assert result_lines(template.render()) == ['foo: 5 15']
+
+    def test_custom_tag_2(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%def name="foo(x, y)">
+                foo: ${x} ${y}
+            </%def>
+            
+            <%def name="bat(g)"><%
+                return "the bat! %s" % g
+            %></%def>
+            
+            <%def name="bar(x)">
+                ${caller.body(z=x)}
+            </%def>
+        """)
+        
+        collection.put_string("index.html", """
+            <%namespace name="myns" file="base.html"/>
+            
+            <%myns:foo x="${'some x'}" y="some y"/>
+            
+            <%myns:bar x="${myns.bat(10)}" args="z">
+                record: ${z}
+            </%myns:bar>
+        
+        """)
+        
+        assert result_lines(collection.get_template("index.html").render()) == [
+            'foo: some x some y', 
+            'record: the bat! 10'
+        ]
+        
+    def test_custom_tag_3(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%namespace name="foo" file="ns.html" inheritable="True"/>
+
+            ${next.body()}
+    """)
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+                caller body: ${caller.body()}
+            </%def>
+        """)
+
+        collection.put_string("index.html", """
+            <%inherit file="base.html"/>
+
+            this is index
+            <%self.foo:bar>
+                call body
+            </%self.foo:bar>
+        """)
+        
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is index",
+            "this is ns.html->bar",
+            "caller body:",
+            "call body"
+        ]
+        
+    def test_custom_tag_case_sensitive(self):
+        t = Template("""
+        <%def name="renderPanel()">
+            panel ${caller.body()}
+        </%def>
+
+        <%def name="renderTablePanel()">
+            <%self:renderPanel>
+                hi
+            </%self:renderPanel>
+        </%def>
+        
+        <%self:renderTablePanel/>
+        """)
+        assert result_lines(t.render()) == ['panel', 'hi']
+        
+        
+    def test_expr_grouping(self):
+        """test that parenthesis are placed around string-embedded expressions."""
+        
+        template = Template("""
+            <%def name="bar(x, y)">
+                ${x}
+                ${y}
+            </%def>
+            
+            <%self:bar x=" ${foo} " y="x${g and '1' or '2'}y"/>
+        """, input_encoding='utf-8')
+
+        # the concat has to come out as "x + (g and '1' or '2') + y"
+        assert result_lines(template.render(foo='this is foo', g=False)) == [
+            "this is foo",
+            "x2y"
+        ]
+
+        
+    def test_ccall(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%namespace name="foo" file="ns.html" inheritable="True"/>
+
+            ${next.body()}
+    """)
+        collection.put_string("ns.html", """
+            <%def name="bar()">
+                this is ns.html->bar
+                caller body: ${caller.body()}
+            </%def>
+        """)
+
+        collection.put_string("index.html", """
+            <%inherit file="base.html"/>
+
+            this is index
+            <%call expr="self.foo.bar()">
+                call body
+            </%call>
+        """)
+
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is index",
+            "this is ns.html->bar",
+            "caller body:",
+            "call body"
+        ]
+
+    def test_ccall_2(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("base.html", """
+            <%namespace name="foo" file="ns1.html" inheritable="True"/>
+
+            ${next.body()}
+    """)
+        collection.put_string("ns1.html", """
+            <%namespace name="foo2" file="ns2.html"/>
+            <%def name="bar()">
+                <%call expr="foo2.ns2_bar()">
+                this is ns1.html->bar
+                caller body: ${caller.body()}
+                </%call>
+            </%def>
+        """)
+
+        collection.put_string("ns2.html", """
+            <%def name="ns2_bar()">
+                this is ns2.html->bar
+                caller body: ${caller.body()}
+            </%def>
+        """)
+
+        collection.put_string("index.html", """
+            <%inherit file="base.html"/>
+
+            this is index
+            <%call expr="self.foo.bar()">
+                call body
+            </%call>
+        """)
+
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is index",
+            "this is ns2.html->bar",
+            "caller body:",
+            "this is ns1.html->bar",
+            "caller body:",
+            "call body"
+        ]
+
+    def test_import(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("functions.html","""
+            <%def name="foo()">
+                this is foo
+            </%def>
+            
+            <%def name="bar()">
+                this is bar
+            </%def>
+            
+            <%def name="lala()">
+                this is lala
+            </%def>
+        """)
+
+        collection.put_string("func2.html", """
+            <%def name="a()">
+                this is a
+            </%def>
+            <%def name="b()">
+                this is b
+            </%def>
+        """)
+        collection.put_string("index.html", """
+            <%namespace file="functions.html" import="*"/>
+            <%namespace file="func2.html" import="a, b"/>
+            ${foo()}
+            ${bar()}
+            ${lala()}
+            ${a()}
+            ${b()}
+            ${x}
+        """)
+
+        assert result_lines(collection.get_template("index.html").render(bar="this is bar", x="this is x")) == [
+            "this is foo",
+            "this is bar",
+            "this is lala",
+            "this is a",
+            "this is b",
+            "this is x"
+        ]
+    
+    def test_import_calledfromdef(self):
+        l = lookup.TemplateLookup()
+        l.put_string("a", """
+        <%def name="table()">
+            im table
+        </%def>
+        """)
+
+        l.put_string("b","""
+        <%namespace file="a" import="table"/>
+
+        <%
+            def table2():
+                table()
+                return ""
+        %>
+
+        ${table2()}
+        """)
+
+        t = l.get_template("b")
+        assert flatten_result(t.render()) == "im table"
+            
+    def test_closure_import(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("functions.html","""
+            <%def name="foo()">
+                this is foo
+            </%def>
+            
+            <%def name="bar()">
+                this is bar
+            </%def>
+        """)
+        
+        collection.put_string("index.html", """
+            <%namespace file="functions.html" import="*"/>
+            <%def name="cl1()">
+                ${foo()}
+            </%def>
+            
+            <%def name="cl2()">
+                ${bar()}
+            </%def>
+            
+            ${cl1()}
+            ${cl2()}
+        """)
+        assert result_lines(collection.get_template("index.html").render(bar="this is bar", x="this is x")) == [
+            "this is foo",
+            "this is bar",
+        ]
+
+    def test_import_local(self):
+        t = Template("""
+            <%namespace import="*">
+                <%def name="foo()">
+                    this is foo
+                </%def>
+            </%namespace>
+            
+            ${foo()}
+        
+        """)
+        assert flatten_result(t.render()) == "this is foo"
+        
+    def test_ccall_import(self):
+        collection = lookup.TemplateLookup()
+        collection.put_string("functions.html","""
+            <%def name="foo()">
+                this is foo
+            </%def>
+            
+            <%def name="bar()">
+                this is bar.
+                ${caller.body()}
+                ${caller.lala()}
+            </%def>
+        """)
+        
+        collection.put_string("index.html", """
+            <%namespace name="func" file="functions.html" import="*"/>
+            <%call expr="bar()">
+                this is index embedded
+                foo is ${foo()}
+                <%def name="lala()">
+                     this is lala ${foo()}
+                </%def>
+            </%call>
+        """)
+        #print collection.get_template("index.html").code
+        #print collection.get_template("functions.html").code
+        assert result_lines(collection.get_template("index.html").render()) == [
+            "this is bar.",
+            "this is index embedded",
+            "foo is",
+            "this is foo",
+            "this is lala",
+            "this is foo"
+        ]
diff --git a/lib3/mako-0.3.6/test/test_pygen.py b/lib3/mako-0.3.6/test/test_pygen.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_pygen.py
@@ -0,0 +1,252 @@
+import unittest
+
+from mako.pygen import PythonPrinter, adjust_whitespace
+from io import StringIO
+
+class GeneratePythonTest(unittest.TestCase):
+    def test_generate_normal(self):
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.writeline("import lala")
+        printer.writeline("for x in foo:")
+        printer.writeline("print x")
+        printer.writeline(None)
+        printer.writeline("print y")
+        assert stream.getvalue() == \
+"""import lala
+for x in foo:
+    print x
+print y
+"""
+    def test_generate_adjusted(self):
+        block = """
+        x = 5 +6
+        if x > 7:
+            for y in range(1,5):
+                print "<td>%s</td>" % y
+"""
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.write_indented_block(block)
+        printer.close()
+        #print stream.getvalue()
+        assert stream.getvalue() == \
+"""
+x = 5 +6
+if x > 7:
+    for y in range(1,5):
+        print "<td>%s</td>" % y
+
+"""
+    def test_generate_combo(self):
+        block = \
+"""
+                x = 5 +6
+                if x > 7:
+                    for y in range(1,5):
+                        print "<td>%s</td>" % y
+                    print "hi"
+                print "there"
+                foo(lala)
+        """
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.writeline("import lala")
+        printer.writeline("for x in foo:")
+        printer.writeline("print x")
+        printer.write_indented_block(block)
+        printer.writeline(None)
+        printer.writeline("print y")
+        printer.close()
+        #print "->" + stream.getvalue().replace(' ', '#') + "<-"
+        assert stream.getvalue() == \
+"""import lala
+for x in foo:
+    print x
+
+    x = 5 +6
+    if x > 7:
+        for y in range(1,5):
+            print "<td>%s</td>" % y
+        print "hi"
+    print "there"
+    foo(lala)
+        
+print y
+"""
+    def test_multi_line(self):
+        block = \
+"""
+    if test:
+        print ''' this is a block of stuff.
+this is more stuff in the block.
+and more block.
+'''
+        do_more_stuff(g)
+"""
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.write_indented_block(block)
+        printer.close()
+        #print stream.getvalue()
+        assert stream.getvalue() == \
+"""
+if test:
+    print ''' this is a block of stuff.
+this is more stuff in the block.
+and more block.
+'''
+    do_more_stuff(g)
+
+"""
+    
+    def test_false_unindentor(self):
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        for line in [
+            "try:",
+            "elsemyvar = 12",
+            "if True:",
+            "print 'hi'",
+            None,
+            "finally:",
+            "dosomething",
+            None
+        ]:
+            printer.writeline(line)
+        
+        assert stream.getvalue() == \
+"""try:
+    elsemyvar = 12
+    if True:
+        print 'hi'
+finally:
+    dosomething
+"""    , stream.getvalue()
+        
+        
+    def test_backslash_line(self):
+        block = \
+"""
+            # comment
+    if test:
+        if (lala + hoho) + \\
+(foobar + blat) == 5:
+            print "hi"
+    print "more indent"
+"""
+        stream = StringIO()
+        printer = PythonPrinter(stream)
+        printer.write_indented_block(block)
+        printer.close()
+        assert stream.getvalue() == \
+"""
+            # comment
+if test:
+    if (lala + hoho) + \\
+(foobar + blat) == 5:
+        print "hi"
+print "more indent"
+
+"""
+
+class WhitespaceTest(unittest.TestCase):
+    def test_basic(self):
+        text = """
+        for x in range(0,15):
+            print x
+        print "hi"
+        """
+        assert adjust_whitespace(text) == \
+"""
+for x in range(0,15):
+    print x
+print "hi"
+"""
+
+    def test_blank_lines(self):
+        text = """
+    print "hi"  # a comment
+    
+    # more comments
+    
+    print g
+"""
+        assert adjust_whitespace(text) == \
+"""
+print "hi"  # a comment
+
+# more comments
+
+print g
+"""        
+    
+    def test_open_quotes_with_pound(self):
+        text = '''
+        print """  this is text
+          # and this is text
+        # and this is too """
+'''
+        assert adjust_whitespace(text) == \
+'''
+print """  this is text
+          # and this is text
+        # and this is too """
+'''
+
+    def test_quote_with_comments(self):
+        text= """
+            print 'hi'
+            # this is a comment
+            # another comment
+            x = 7 # someone's '''comment
+            print '''
+        there
+        '''
+            # someone else's comment
+"""
+
+        assert adjust_whitespace(text) == \
+"""
+print 'hi'
+# this is a comment
+# another comment
+x = 7 # someone's '''comment
+print '''
+        there
+        '''
+# someone else's comment
+"""        
+
+
+    def test_quotes_with_pound(self):
+        text = '''
+        if True:
+            """#"""
+        elif False:
+            "bar"
+'''
+        assert adjust_whitespace(text) == \
+'''
+if True:
+    """#"""
+elif False:
+    "bar"
+'''
+
+    def test_quotes(self):
+        text = """
+        print ''' aslkjfnas kjdfn
+askdjfnaskfd fkasnf dknf sadkfjn asdkfjna sdakjn
+asdkfjnads kfajns '''
+        if x:
+            print y
+"""
+        assert adjust_whitespace(text) == \
+"""
+print ''' aslkjfnas kjdfn
+askdjfnaskfd fkasnf dknf sadkfjn asdkfjna sdakjn
+asdkfjnads kfajns '''
+if x:
+    print y
+"""
diff --git a/lib3/mako-0.3.6/test/test_template.py b/lib3/mako-0.3.6/test/test_template.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_template.py
@@ -0,0 +1,936 @@
+# -*- coding: utf-8 -*-
+
+from mako.template import Template, ModuleTemplate
+from mako.lookup import TemplateLookup
+from mako.ext.preprocessors import convert_comments
+from mako import exceptions, util
+import re, os
+from .util import flatten_result, result_lines
+import codecs
+from test import TemplateTest, eq_, template_base, module_base, skip_if, assert_raises
+
+class EncodingTest(TemplateTest):
+    def test_unicode(self):
+        self._do_memory_test(
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+    def test_encoding_doesnt_conflict(self):
+        self._do_memory_test(
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            output_encoding='utf-8'
+        )
+        
+    def test_unicode_arg(self):
+        val = """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        self._do_memory_test(
+            "${val}",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            template_args={'val':val}
+        )
+
+    def test_unicode_file(self):
+        self._do_file_test(
+            "unicode.html",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+    def test_unicode_file_code(self):
+        self._do_file_test(
+            'unicode_code.html',
+            """hi, drôle de petite voix m’a réveillé.""",
+            filters=flatten_result
+        )
+
+    def test_unicode_file_lookup(self):
+        lookup = TemplateLookup(
+                    directories=[template_base], 
+                    output_encoding='utf-8', 
+                    default_filters=['decode.utf8'])
+        if util.py3k:
+            template = lookup.get_template('/chs_unicode_py3k.html')
+        else:
+            template = lookup.get_template('/chs_unicode.html')
+        eq_(
+            flatten_result(template.render_unicode(name='毛泽东')),
+            '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京.'
+        )
+
+    def test_unicode_bom(self):
+        self._do_file_test(
+            'bom.html',
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+        self._do_file_test(
+            'bommagic.html',
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+        self.assertRaises(
+            exceptions.CompileException,
+            Template, filename=self._file_path('badbom.html'),
+            module_directory=module_base
+        )
+
+    def test_unicode_memory(self):
+        val = """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        self._do_memory_test(
+            ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'),
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+    
+    def test_unicode_text(self):
+        val = """<%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »</%text>"""
+        self._do_memory_test(
+            ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'),
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        )
+
+    def test_unicode_text_ccall(self):
+        val = """
+        <%def name="foo()">
+            ${capture(caller.body)}
+        </%def>
+        <%call expr="foo()">
+        <%text>Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »</%text>
+        </%call>"""
+        self._do_memory_test(
+            ("## -*- coding: utf-8 -*-\n" + val).encode('utf-8'),
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            filters=flatten_result
+        )
+        
+    def test_unicode_literal_in_expr(self):
+        if util.py3k:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                ${"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
+                """.encode('utf-8'),
+                """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+                filters = lambda s:s.strip()
+            )
+        else:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                ${u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"}
+                """.encode('utf-8'),
+                """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+                filters = lambda s:s.strip()
+            )
+
+    def test_unicode_literal_in_expr_file(self):
+        self._do_file_test(
+            'unicode_expr.html',
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            lambda t:t.strip()
+        )
+
+    def test_unicode_literal_in_code(self):
+        if util.py3k:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%
+                    context.write("Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »")
+                %>
+                """.encode('utf-8'),
+                """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+                filters=lambda s:s.strip()
+            )
+        else:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%
+                    context.write(u"Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »")
+                %>
+                """.encode('utf-8'),
+                """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+                filters=lambda s:s.strip()
+            )
+    
+    def test_unicode_literal_in_controlline(self):
+        if util.py3k:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%
+                    x = "drôle de petite voix m’a réveillé."
+                %>
+                % if x=="drôle de petite voix m’a réveillé.":
+                    hi, ${x}
+                % endif
+                """.encode('utf-8'),
+                """hi, drôle de petite voix m’a réveillé.""",
+                filters=lambda s:s.strip(),
+            )
+        else:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%
+                    x = u"drôle de petite voix m’a réveillé."
+                %>
+                % if x==u"drôle de petite voix m’a réveillé.":
+                    hi, ${x}
+                % endif
+                """.encode('utf-8'),
+                """hi, drôle de petite voix m’a réveillé.""",
+                filters=lambda s:s.strip(),
+            )
+    
+    def test_unicode_literal_in_tag(self):
+        self._do_file_test(
+            "unicode_arguments.html",
+            [
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+            ],
+            filters=result_lines
+        )
+
+        self._do_memory_test(
+            open(self._file_path("unicode_arguments.html"), 'rb').read(),
+            [
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+                'x is: drôle de petite voix m’a réveillé',
+            ],
+            filters=result_lines
+        )
+        
+    def test_unicode_literal_in_def(self):
+        if util.py3k:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%def name="bello(foo, bar)">
+                Foo: ${ foo }
+                Bar: ${ bar }
+                </%def>
+                <%call expr="bello(foo='árvíztűrő tükörfúrógép', bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+                </%call>""".encode('utf-8'),
+                """Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP""",
+                filters=flatten_result
+            )
+
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%def name="hello(foo='árvíztűrő tükörfúrógép', bar='ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+                Foo: ${ foo }
+                Bar: ${ bar }
+                </%def>
+                ${ hello() }""".encode('utf-8'),
+                """Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP""",
+                filters=flatten_result
+            )
+        else:
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%def name="bello(foo, bar)">
+                Foo: ${ foo }
+                Bar: ${ bar }
+                </%def>
+                <%call expr="bello(foo=u'árvíztűrő tükörfúrógép', bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+                </%call>""".encode('utf-8'),
+                """Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP""",
+                filters=flatten_result
+            )
+        
+            self._do_memory_test(
+                """## -*- coding: utf-8 -*-
+                <%def name="hello(foo=u'árvíztűrő tükörfúrógép', bar=u'ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP')">
+                Foo: ${ foo }
+                Bar: ${ bar }
+                </%def>
+                ${ hello() }""".encode('utf-8'),
+                """Foo: árvíztűrő tükörfúrógép Bar: ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP""",
+                filters=flatten_result
+            )
+        
+    def test_input_encoding(self):
+        """test the 'input_encoding' flag on Template, and that unicode 
+            objects arent double-decoded"""
+        
+        if util.py3k:
+            self._do_memory_test(
+                "hello ${f('śląsk')}",
+                "hello śląsk",
+                input_encoding='utf-8',
+                template_args={'f':lambda x:x}
+            )    
+
+            self._do_memory_test(
+                "## -*- coding: utf-8 -*-\nhello ${f('śląsk')}",
+                "hello śląsk",
+                template_args={'f':lambda x:x}
+            )
+        else:
+            self._do_memory_test(
+                "hello ${f(u'śląsk')}",
+                "hello śląsk",
+                input_encoding='utf-8',
+                template_args={'f':lambda x:x}
+            )    
+
+            self._do_memory_test(
+                "## -*- coding: utf-8 -*-\nhello ${f(u'śląsk')}",
+                "hello śląsk",
+                template_args={'f':lambda x:x}
+            )
+
+    def test_raw_strings(self):
+        """test that raw strings go straight thru with default_filters turned off"""
+
+        self._do_memory_test(
+            "## -*- coding: utf-8 -*-\nhello ${x}",
+            "hello śląsk",
+            default_filters=[],
+            template_args={'x':'śląsk'},
+            unicode_=False
+        )
+
+        # now, the way you *should* be doing it....
+        self._do_memory_test(
+            "## -*- coding: utf-8 -*-\nhello ${x}",
+            "hello śląsk",
+            template_args={'x':'śląsk'}
+        )
+        
+    def test_encoding(self):
+        self._do_memory_test(
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""",
+            """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »""".encode('utf-8'),
+            output_encoding='utf-8',
+            unicode_=False
+        )
+
+    def test_encoding_errors(self):
+        self._do_memory_test(
+            """KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: Комит́ет Госуд́арственной Безоп́асности (help·info); Komitet Gosudarstvennoy Bezopasnosti)""",
+            """KGB (transliteration of "КГБ") is the Russian-language abbreviation for Committee for State Security, (Russian: Комит́ет Госуд́арственной Безоп́асности (help·info); Komitet Gosudarstvennoy Bezopasnosti)""".encode('iso-8859-1', 'replace'),
+            output_encoding='iso-8859-1', encoding_errors='replace',
+            unicode_=False
+        )
+    
+    def test_read_unicode(self):
+        lookup = TemplateLookup(directories=[template_base], 
+                                filesystem_checks=True, output_encoding='utf-8')
+        if util.py3k:
+            template = lookup.get_template('/read_unicode_py3k.html')
+        else:
+            template = lookup.get_template('/read_unicode.html')
+        data = template.render(path=self._file_path('internationalization.html'))
+
+    @skip_if(lambda: util.py3k)
+    def test_bytestring_passthru(self):
+        self._do_file_test(
+            'chs_utf8.html',
+            '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.',
+            default_filters=[],
+            disable_unicode=True,
+            template_args={'name':'毛泽东'},
+            filters=flatten_result, 
+            unicode_=False
+        )
+
+        self._do_file_test(
+            'chs_utf8.html',
+            '毛泽东 是 新中国的主席<br/> Welcome 你 to 北京. Welcome 你 to 北京.',
+            disable_unicode=True,
+            template_args={'name':'毛泽东'},
+            filters=flatten_result,
+            unicode_=False
+        )
+
+        template = self._file_template('chs_utf8.html', disable_unicode=True)
+        self.assertRaises(UnicodeDecodeError, template.render_unicode, name='毛泽东')
+
+        template = Template("""${'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »'}""", disable_unicode=True, input_encoding='utf-8')
+        assert template.render() == """Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        template = Template("""${'Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petite voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »'}""", input_encoding='utf8', output_encoding='utf8', disable_unicode=False, default_filters=[])
+        self.assertRaises(UnicodeDecodeError, template.render)  # raises because expression contains an encoded bytestring which cannot be decoded
+
+
+class PageArgsTest(TemplateTest):
+    def test_basic(self):
+        template = Template("""
+            <%page args="x, y, z=7"/>
+            
+            this is page, ${x}, ${y}, ${z}
+""")
+
+        assert flatten_result(template.render(x=5, y=10)) == "this is page, 5, 10, 7"
+        assert flatten_result(template.render(x=5, y=10, z=32)) == "this is page, 5, 10, 32"
+        try:
+            template.render(y=10)
+            assert False
+        except TypeError as e:
+            assert True
+    
+    def test_inherits(self):
+        lookup = TemplateLookup()
+        lookup.put_string("base.tmpl",
+        """
+        <%page args="bar" />
+        ${bar}
+        ${pageargs['foo']}
+        ${self.body(**pageargs)}
+        """
+        )
+        lookup.put_string("index.tmpl", """
+        <%inherit file="base.tmpl" />
+        <%page args="variable" />
+        ${variable}
+        """)
+
+        self._do_test(
+            lookup.get_template("index.tmpl"),
+            "bar foo var",
+            filters=flatten_result,
+            template_args={'variable':'var', 'bar':'bar', 'foo':'foo'}
+            
+        )
+
+    def test_includes(self):
+        lookup = TemplateLookup()
+        lookup.put_string("incl1.tmpl",
+        """
+        <%page args="bar" />
+        ${bar}
+        ${pageargs['foo']}
+        """
+        )
+        lookup.put_string("incl2.tmpl",
+        """
+        ${pageargs}
+        """
+        )
+        lookup.put_string("index.tmpl", """
+        <%include file="incl1.tmpl" args="**pageargs"/>
+        <%page args="variable" />
+        ${variable}
+        <%include file="incl2.tmpl" />
+        """)
+
+        self._do_test(
+            lookup.get_template("index.tmpl"),
+            "bar foo var {}",
+            filters=flatten_result,
+            template_args={'variable':'var', 'bar':'bar', 'foo':'foo'}
+
+        )
+        
+    def test_with_context(self):
+        template = Template("""
+            <%page args="x, y, z=7"/>
+
+            this is page, ${x}, ${y}, ${z}, ${w}
+""")
+        #print template.code
+        assert flatten_result(template.render(x=5, y=10, w=17)) == "this is page, 5, 10, 7, 17"
+
+    def test_overrides_builtins(self):
+        template = Template("""
+            <%page args="id"/>
+            
+            this is page, id is ${id}
+        """)
+        
+        assert flatten_result(template.render(id="im the id")) == "this is page, id is im the id"
+    
+    def test_canuse_builtin_names(self):
+        template = Template("""
+            exception: ${Exception}
+            id: ${id}
+        """)
+        assert flatten_result(template.render(id='some id', Exception='some exception')) == "exception: some exception id: some id"
+
+    def test_builtin_names_dont_clobber_defaults_in_includes(self):
+        lookup = TemplateLookup()
+        lookup.put_string("test.mako", 
+        """
+        <%include file="test1.mako"/>
+
+        """)
+
+        lookup.put_string("test1.mako", """
+        <%page args="id='foo'"/>
+
+        ${id}
+        """)
+
+        for template in ("test.mako", "test1.mako"):
+            assert flatten_result(lookup.get_template(template).render()) == "foo"
+            assert flatten_result(lookup.get_template(template).render(id=5)) == "5"
+            assert flatten_result(lookup.get_template(template).render(id=id)) == "<built-in function id>"
+    
+    def test_dict_locals(self):
+        template = Template("""
+            <%
+                dict = "this is dict"
+                locals = "this is locals"
+            %>
+            dict: ${dict}
+            locals: ${locals}
+        """)
+        assert flatten_result(template.render()) == "dict: this is dict locals: this is locals"
+
+class IncludeTest(TemplateTest):
+    def test_basic(self):
+        lookup = TemplateLookup()
+        lookup.put_string("a", """
+            this is a
+            <%include file="b" args="a=3,b=4,c=5"/>
+        """)
+        lookup.put_string("b", """
+            <%page args="a,b,c"/>
+            this is b.  ${a}, ${b}, ${c}
+        """)
+        assert flatten_result(lookup.get_template("a").render()) == "this is a this is b. 3, 4, 5"
+
+    def test_localargs(self):
+        lookup = TemplateLookup()
+        lookup.put_string("a", """
+            this is a
+            <%include file="b" args="a=a,b=b,c=5"/>
+        """)
+        lookup.put_string("b", """
+            <%page args="a,b,c"/>
+            this is b.  ${a}, ${b}, ${c}
+        """)
+        assert flatten_result(lookup.get_template("a").render(a=7,b=8)) == "this is a this is b. 7, 8, 5"
+    
+    def test_viakwargs(self):    
+        lookup = TemplateLookup()
+        lookup.put_string("a", """
+            this is a
+            <%include file="b" args="c=5, **context.kwargs"/>
+        """)
+        lookup.put_string("b", """
+            <%page args="a,b,c"/>
+            this is b.  ${a}, ${b}, ${c}
+        """)
+        #print lookup.get_template("a").code
+        assert flatten_result(lookup.get_template("a").render(a=7,b=8)) == "this is a this is b. 7, 8, 5"
+
+    def test_include_withargs(self):
+        lookup = TemplateLookup()
+        lookup.put_string("a", """
+            this is a
+            <%include file="${i}" args="c=5, **context.kwargs"/>
+        """)
+        lookup.put_string("b", """
+            <%page args="a,b,c"/>
+            this is b.  ${a}, ${b}, ${c}
+        """)
+        assert flatten_result(lookup.get_template("a").render(a=7,b=8,i='b')) == "this is a this is b. 7, 8, 5"
+    
+    def test_within_ccall(self):
+        lookup = TemplateLookup()
+        lookup.put_string("a", """this is a""")
+        lookup.put_string("b", """
+        <%def name="bar()">
+            bar: ${caller.body()}
+            <%include file="a"/>
+        </%def>
+        """)
+        lookup.put_string("c", """
+        <%namespace name="b" file="b"/>
+        <%b:bar>
+            calling bar
+        </%b:bar>
+        """)
+        assert flatten_result(lookup.get_template("c").render()) == "bar: calling bar this is a"
+
+class UndefinedVarsTest(TemplateTest):
+    def test_undefined(self):
+        t = Template("""
+            % if x is UNDEFINED:
+                undefined
+            % else:
+                x: ${x}
+            % endif
+        """)
+        
+        assert result_lines(t.render(x=12)) == ["x: 12"]
+        assert result_lines(t.render(y=12)) == ["undefined"]
+
+    def test_strict(self):
+        t = Template("""
+            % if x is UNDEFINED:
+                undefined
+            % else:
+                x: ${x}
+            % endif
+        """, strict_undefined=True)
+        
+        assert result_lines(t.render(x=12)) == ['x: 12']
+        
+        assert_raises(
+            NameError,
+            t.render, y=12
+        )
+        
+        l = TemplateLookup(strict_undefined=True)
+        l.put_string("a", "some template")
+        l.put_string("b", """
+            <%namespace name='a' file='a' import='*'/>
+            % if x is UNDEFINED:
+                undefined
+            % else:
+                x: ${x}
+            % endif
+        """)
+
+        assert result_lines(t.render(x=12)) == ['x: 12']
+        
+        assert_raises(
+            NameError,
+            t.render, y=12
+        )
+    
+    def test_expression_declared(self):
+        t = Template("""
+            ${",".join([t for t in ("a", "b", "c")])}
+        """, strict_undefined=True)
+        
+        eq_(result_lines(t.render()), ['a,b,c'])
+
+        t = Template("""
+            <%self:foo value="${[(val, n) for val, n in [(1, 2)]]}"/>
+            
+            <%def name="foo(value)">
+                ${value}
+            </%def>
+            
+        """, strict_undefined=True)
+        
+        eq_(result_lines(t.render()), ['[(1, 2)]'])
+
+        t = Template("""
+            <%call expr="foo(value=[(val, n) for val, n in [(1, 2)]])" />
+            
+            <%def name="foo(value)">
+                ${value}
+            </%def>
+            
+        """, strict_undefined=True)
+        
+        eq_(result_lines(t.render()), ['[(1, 2)]'])
+        
+        l = TemplateLookup(strict_undefined=True)
+        l.put_string("i", "hi, ${pageargs['y']}")
+        l.put_string("t", """
+            <%include file="i" args="y=[x for x in range(3)]" />
+        """)
+        eq_(
+            result_lines(l.get_template("t").render()), ['hi, [0, 1, 2]']
+        )
+        
+        l.put_string('q', """
+            <%namespace name="i" file="${(str([x for x in range(3)][2]) + 'i')[-1]}" />
+            ${i.body(y='x')}
+        """)
+        eq_(
+            result_lines(l.get_template("q").render()), ['hi, x']
+        )
+
+        t = Template("""
+            <%
+                y = lambda q: str(q)
+            %>
+            ${y('hi')}
+        """, strict_undefined=True)
+        eq_(
+            result_lines(t.render()), ["hi"]
+        )
+
+    def test_list_comprehensions_plus_undeclared_nonstrict(self):
+        # traditional behavior.  variable inside a list comprehension
+        # is treated as an "undefined", so is pulled from the context.
+        t = Template("""
+            t is: ${t}
+        
+            ${",".join([t for t in ("a", "b", "c")])}
+        """)
+        
+        eq_(
+            result_lines(t.render(t="T")),
+            ['t is: T', 'a,b,c'] 
+        )
+    
+    def test_traditional_assignment_plus_undeclared(self):
+        t = Template("""
+            t is: ${t}
+            
+            <%
+                t = 12
+            %>
+        """)
+        assert_raises(
+            UnboundLocalError,
+            t.render, t="T"
+        )
+        
+    def test_list_comprehensions_plus_undeclared_strict(self):
+        # with strict, a list comprehension now behaves
+        # like the undeclared case above.
+        t = Template("""
+            t is: ${t}
+        
+            ${",".join([t for t in ("a", "b", "c")])}
+        """, strict_undefined=True)
+        
+        eq_(
+            result_lines(t.render(t="T")),
+            ['t is: T', 'a,b,c']
+        )
+    
+        
+class ControlTest(TemplateTest):
+    def test_control(self):
+        t = Template("""
+    ## this is a template.
+    % for x in y:
+    %   if 'test' in x:
+        yes x has test
+    %   else:
+        no x does not have test
+    %endif
+    %endfor
+""")
+        assert result_lines(t.render(y=[{'test':'one'}, {'foo':'bar'}, {'foo':'bar', 'test':'two'}])) == [
+            "yes x has test",
+            "no x does not have test",
+            "yes x has test"
+        ]
+    
+    def test_blank_control(self):
+        self._do_memory_test(
+            """
+            % if True:
+            % endif
+            """,
+            "",
+            filters=lambda s:s.strip()
+        )
+        
+    def test_multiline_control(self):
+        t = Template("""
+    % for x in \\
+        [y for y in [1,2,3]]:
+        ${x}
+    % endfor
+""")
+        #print t.code
+        assert flatten_result(t.render()) == "1 2 3"
+        
+class GlobalsTest(TemplateTest):
+    def test_globals(self):
+        self._do_memory_test(
+            """
+                <%!
+                    y = "hi"
+                %>
+            y is ${y}
+            """,
+            "y is hi",
+            filters=lambda t:t.strip()
+        )
+
+class RichTracebackTest(TemplateTest):
+    
+    def _do_test_traceback(self, utf8, memory, syntax):
+        if memory:
+            if syntax:
+                source = '## coding: utf-8\n<% print "m’a réveillé. '\
+                        'Elle disait: « S’il vous plaît… dessine-moi un mouton! » %>'
+            else:
+                source = '## coding: utf-8\n<% print u"m’a réveillé. '\
+                        'Elle disait: « S’il vous plaît… dessine-moi un mouton! »" + str(5/0) %>'
+            if utf8:
+                source = source.encode('utf-8')
+            else:
+                source = source
+            templateargs = {'text':source}
+        else:
+            if syntax:
+                filename = 'unicode_syntax_error.html'
+            else:
+                filename = 'unicode_runtime_error.html'
+            source = open(self._file_path(filename), 'rb').read()
+            if not utf8:
+                source = source.decode('utf-8')
+            templateargs = {'filename':self._file_path(filename)}
+        try:
+            template = Template(**templateargs)
+            if not syntax:
+                template.render_unicode()
+            assert False
+        except Exception as e:
+            tback = exceptions.RichTraceback()
+            if utf8:
+                assert tback.source == source.decode('utf-8')
+            else:
+                assert tback.source == source
+
+for utf8 in (True, False):
+    for memory in (True, False):
+        for syntax in (True, False):
+            def _do_test(self):
+                self._do_test_traceback(utf8, memory, syntax)
+            name = 'test_%s_%s_%s' % (utf8 and 'utf8' or 'unicode', 
+                                        memory and 'memory' or 'file', 
+                                        syntax and 'syntax' or 'runtime')
+            _do_test.__name__ = name
+            setattr(RichTracebackTest, name, _do_test)
+            del _do_test
+
+class ModuleDirTest(TemplateTest):
+    def test_basic(self):
+        t = self._file_template("modtest.html")
+        t2 = self._file_template('subdir/modtest.html')
+
+        eq_(
+            t.module.__file__,
+            os.path.join(module_base, 'modtest.html.py')
+        )
+        eq_(
+            t2.module.__file__,
+            os.path.join(module_base, 'subdir', 'modtest.html.py')
+        )
+ 
+    def test_callable(self):
+        def get_modname(filename, uri):
+            return os.path.join(
+                        module_base, 
+                        os.path.dirname(uri)[1:], 
+                        'foo', 
+                        os.path.basename(filename) + ".py")
+
+        lookup = TemplateLookup(template_base, modulename_callable=get_modname)
+        t = lookup.get_template('/modtest.html')
+        t2 = lookup.get_template('/subdir/modtest.html')
+        eq_(
+            t.module.__file__, 
+            os.path.join(module_base, 'foo', 'modtest.html.py')
+        )
+        eq_(
+            t2.module.__file__, 
+            os.path.join(module_base, 'subdir', 'foo', 'modtest.html.py')
+        )
+
+class FilenameToURITest(TemplateTest):
+    def test_windows_paths(self):
+        """test that windows filenames are handled appropriately by Template."""
+        
+        current_path = os.path
+        import ntpath
+        os.path = ntpath
+        try:
+            class NoCompileTemplate(Template):
+                def _compile_from_file(self, path, filename):
+                    self.path = path
+                    return Template("foo bar").module
+                    
+            t1 = NoCompileTemplate(
+                                    filename="c:\\foo\\template.html", 
+                                    module_directory="c:\\modules\\")
+            
+            eq_(t1.uri, "/foo/template.html")
+            eq_(t1.path, "c:\\modules\\foo\\template.html.py")
+
+            t1 = NoCompileTemplate(
+                                    filename="c:\\path\\to\\templates\\template.html", 
+                                    uri = "/bar/template.html",
+                                    module_directory="c:\\modules\\")
+            
+            eq_(t1.uri, "/bar/template.html")
+            eq_(t1.path, "c:\\modules\\bar\\template.html.py")
+
+        finally:
+            os.path = current_path
+
+    def test_posix_paths(self):
+        """test that posixs filenames are handled appropriately by Template."""
+
+        current_path = os.path
+        import posixpath
+        os.path = posixpath
+        try:
+            class NoCompileTemplate(Template):
+                def _compile_from_file(self, path, filename):
+                    self.path = path
+                    return Template("foo bar").module
+
+            t1 = NoCompileTemplate(
+                                    filename="/var/www/htdocs/includes/template.html", 
+                                    module_directory="/var/lib/modules")
+
+            eq_(t1.uri, "/var/www/htdocs/includes/template.html")
+            eq_(t1.path, "/var/lib/modules/var/www/htdocs/includes/template.html.py")
+
+            t1 = NoCompileTemplate(
+                                    filename="/var/www/htdocs/includes/template.html", 
+                                    uri = "/bar/template.html",
+                                    module_directory="/var/lib/modules")
+
+            eq_(t1.uri, "/bar/template.html")
+            eq_(t1.path, "/var/lib/modules/bar/template.html.py")
+
+        finally:
+            os.path = current_path
+        
+    
+    
+class ModuleTemplateTest(TemplateTest):
+    def test_module_roundtrip(self):
+        lookup = TemplateLookup()
+
+        template = Template("""
+        <%inherit file="base.html"/>
+        
+        % for x in range(5):
+            ${x}
+        % endfor
+""", lookup=lookup)
+
+        base = Template("""
+        This is base.
+        ${self.body()}
+""", lookup=lookup)
+
+        lookup.put_template("base.html", base)
+        lookup.put_template("template.html", template)
+        
+        assert result_lines(template.render()) == [
+            "This is base.", "0", "1", "2", "3", "4"
+        ]
+        
+        lookup = TemplateLookup()
+        template = ModuleTemplate(template.module, lookup=lookup)
+        base = ModuleTemplate(base.module, lookup=lookup)
+
+        lookup.put_template("base.html", base)
+        lookup.put_template("template.html", template)
+        
+        assert result_lines(template.render()) == [
+            "This is base.", "0", "1", "2", "3", "4"
+        ]
+        
+    
+class PreprocessTest(TemplateTest):
+    def test_old_comments(self):
+        t = Template("""
+        im a template
+# old style comment
+    # more old style comment
+    
+    ## new style comment
+    - # not a comment
+    - ## not a comment
+""", preprocessor=convert_comments)
+
+        assert flatten_result(t.render()) == "im a template - # not a comment - ## not a comment"
diff --git a/lib3/mako-0.3.6/test/test_tgplugin.py b/lib3/mako-0.3.6/test/test_tgplugin.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/test_tgplugin.py
@@ -0,0 +1,42 @@
+import unittest
+
+from mako.ext.turbogears import TGPlugin
+from .util import flatten_result, result_lines
+from test import TemplateTest, template_base
+
+tl = TGPlugin(options=dict(directories=[template_base]), extension='html')
+
+class TestTGPlugin(TemplateTest):
+    def test_basic(self):
+        t = tl.load_template('/index.html')
+        assert result_lines(t.render()) == [
+            "this is index"
+        ]
+    def test_subdir(self):
+        t = tl.load_template('/subdir/index.html')
+        assert result_lines(t.render()) == [
+            "this is sub index",
+            "this is include 2"
+
+        ]
+
+        assert tl.load_template('/subdir/index.html').module_id == '_subdir_index_html'
+
+    def test_basic_dot(self):
+        t = tl.load_template('index')
+        assert result_lines(t.render()) == [
+            "this is index"
+        ]
+    def test_subdir_dot(self):
+        t = tl.load_template('subdir.index')
+        assert result_lines(t.render()) == [
+            "this is sub index",
+            "this is include 2"
+
+        ]
+
+        assert tl.load_template('subdir.index').module_id == '_subdir_index_html'
+    
+    def test_string(self):
+        t = tl.load_template('foo', "hello world")
+        assert t.render() == "hello world"
diff --git a/lib3/mako-0.3.6/test/util.py b/lib3/mako-0.3.6/test/util.py
new file mode 100644
--- /dev/null
+++ b/lib3/mako-0.3.6/test/util.py
@@ -0,0 +1,7 @@
+import re
+
+def flatten_result(result):
+    return re.sub(r'[\s\r\n]+', ' ', result).strip()
+
+def result_lines(result):
+    return [x.strip() for x in re.split(r'\r?\n', re.sub(r' +', ' ', result)) if x.strip() != '']
\ No newline at end of file
diff --git a/lib3/pkg_resources.py b/lib3/pkg_resources.py
deleted file mode 100644
--- a/lib3/pkg_resources.py
+++ /dev/null
@@ -1,2838 +0,0 @@
-"""Package resource API
---------------------
-
-A resource is a logical file contained within a package, or a logical
-subdirectory thereof.  The package resource API expects resource names
-to have their path parts separated with ``/``, *not* whatever the local
-path separator is.  Do not use os.path operations to manipulate resource
-names being passed into the API.
-
-The package resource API is designed to work with normal filesystem packages,
-.egg files, and unpacked .egg files.  It can also work in a limited way with
-.zip files and with custom PEP 302 loaders that support the ``get_data()``
-method.
-"""
-
-import sys, os, zipimport, time, re, imp, types
-from urllib.parse import urlparse, urlunparse
-
-try:
-    frozenset
-except NameError:
-    from sets import ImmutableSet as frozenset
-
-# capture these to bypass sandboxing
-from os import utime
-try:
-    from os import mkdir, rename, unlink
-    WRITE_SUPPORT = True
-except ImportError:
-    # no write support, probably under GAE
-    WRITE_SUPPORT = False
-
-from os import open as os_open
-from os.path import isdir, split
-
-# This marker is used to simplify the process that checks is the
-# setuptools package was installed by the Setuptools project
-# or by the Distribute project, in case Setuptools creates
-# a distribution with the same version.
-#
-# The bootstrapping script for instance, will check if this
-# attribute is present to decide wether to reinstall the package
-_distribute = True
-
-def _bypass_ensure_directory(name, mode=0o777):
-    # Sandbox-bypassing version of ensure_directory()
-    if not WRITE_SUPPORT:
-        raise IOError('"os.mkdir" not supported on this platform.')
-    dirname, filename = split(name)
-    if dirname and filename and not isdir(dirname):
-        _bypass_ensure_directory(dirname)
-        mkdir(dirname, mode)
-
-
-_state_vars = {}
-
-def _declare_state(vartype, **kw):
-    g = globals()
-    for name, val in kw.items():
-        g[name] = val
-        _state_vars[name] = vartype
-
-def __getstate__():
-    state = {}
-    g = globals()
-    for k, v in _state_vars.items():
-        state[k] = g['_sget_'+v](g[k])
-    return state
-
-def __setstate__(state):
-    g = globals()
-    for k, v in state.items():
-        g['_sset_'+_state_vars[k]](k, g[k], v)
-    return state
-
-def _sget_dict(val):
-    return val.copy()
-
-def _sset_dict(key, ob, state):
-    ob.clear()
-    ob.update(state)
-
-def _sget_object(val):
-    return val.__getstate__()
-
-def _sset_object(key, ob, state):
-    ob.__setstate__(state)
-
-_sget_none = _sset_none = lambda *args: None
-
-
-
-def get_supported_platform():
-    """Return this platform's maximum compatible version.
-
-    distutils.util.get_platform() normally reports the minimum version
-    of Mac OS X that would be required to *use* extensions produced by
-    distutils.  But what we want when checking compatibility is to know the
-    version of Mac OS X that we are *running*.  To allow usage of packages that
-    explicitly require a newer version of Mac OS X, we must also know the
-    current version of the OS.
-
-    If this condition occurs for any other platform with a version in its
-    platform strings, this function should be extended accordingly.
-    """
-    plat = get_build_platform(); m = macosVersionString.match(plat)
-    if m is not None and sys.platform == "darwin":
-        try:
-            plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3))
-        except ValueError:
-            pass    # not Mac OS X
-    return plat
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-__all__ = [
-    # Basic resource access and distribution/entry point discovery
-    'require', 'run_script', 'get_provider',  'get_distribution',
-    'load_entry_point', 'get_entry_map', 'get_entry_info', 'iter_entry_points',
-    'resource_string', 'resource_stream', 'resource_filename',
-    'resource_listdir', 'resource_exists', 'resource_isdir',
-
-    # Environmental control
-    'declare_namespace', 'working_set', 'add_activation_listener',
-    'find_distributions', 'set_extraction_path', 'cleanup_resources',
-    'get_default_cache',
-
-    # Primary implementation classes
-    'Environment', 'WorkingSet', 'ResourceManager',
-    'Distribution', 'Requirement', 'EntryPoint',
-
-    # Exceptions
-    'ResolutionError','VersionConflict','DistributionNotFound','UnknownExtra',
-    'ExtractionError',
-
-    # Parsing functions and string utilities
-    'parse_requirements', 'parse_version', 'safe_name', 'safe_version',
-    'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections',
-    'safe_extra', 'to_filename',
-
-    # filesystem utilities
-    'ensure_directory', 'normalize_path',
-
-    # Distribution "precedence" constants
-    'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST',
-
-    # "Provider" interfaces, implementations, and registration/lookup APIs
-    'IMetadataProvider', 'IResourceProvider', 'FileMetadata',
-    'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider',
-    'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider',
-    'register_finder', 'register_namespace_handler', 'register_loader_type',
-    'fixup_namespace_packages', 'get_importer',
-
-    # Deprecated/backward compatibility only
-    'run_main', 'AvailableDistributions',
-]
-class ResolutionError(Exception):
-    """Abstract base for dependency resolution errors"""
-    def __repr__(self):
-        return self.__class__.__name__+repr(self.args)
-
-class VersionConflict(ResolutionError):
-    """An already-installed version conflicts with the requested version"""
-
-class DistributionNotFound(ResolutionError):
-    """A requested distribution was not found"""
-
-class UnknownExtra(ResolutionError):
-    """Distribution doesn't have an "extra feature" of the given name"""
-_provider_factories = {}
-
-PY_MAJOR = sys.version[:3]
-EGG_DIST    = 3
-BINARY_DIST = 2
-SOURCE_DIST = 1
-CHECKOUT_DIST = 0
-DEVELOP_DIST = -1
-
-def register_loader_type(loader_type, provider_factory):
-    """Register `provider_factory` to make providers for `loader_type`
-
-    `loader_type` is the type or class of a PEP 302 ``module.__loader__``,
-    and `provider_factory` is a function that, passed a *module* object,
-    returns an ``IResourceProvider`` for that module.
-    """
-    _provider_factories[loader_type] = provider_factory
-
-def get_provider(moduleOrReq):
-    """Return an IResourceProvider for the named module or requirement"""
-    if isinstance(moduleOrReq,Requirement):
-        return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
-    try:
-        module = sys.modules[moduleOrReq]
-    except KeyError:
-        __import__(moduleOrReq)
-        module = sys.modules[moduleOrReq]
-    loader = getattr(module, '__loader__', None)
-    return _find_adapter(_provider_factories, loader)(module)
-
-def _macosx_vers(_cache=[]):
-    if not _cache:
-        import platform
-        version = platform.mac_ver()[0]
-        # fallback for MacPorts
-        if version == '':
-            import plistlib
-            plist = '/System/Library/CoreServices/SystemVersion.plist'
-            if os.path.exists(plist):
-                if hasattr(plistlib, 'readPlist'):
-                    plist_content = plistlib.readPlist(plist)
-                    if 'ProductVersion' in plist_content:
-                        version = plist_content['ProductVersion']
-
-        _cache.append(version.split('.'))
-    return _cache[0]
-
-def _macosx_arch(machine):
-    return {'PowerPC':'ppc', 'Power_Macintosh':'ppc'}.get(machine,machine)
-
-def get_build_platform():
-    """Return this platform's string for platform-specific distributions
-
-    XXX Currently this is the same as ``distutils.util.get_platform()``, but it
-    needs some hacks for Linux and Mac OS X.
-    """
-    try:
-        from distutils.util import get_platform
-    except ImportError:
-        from sysconfig import get_platform
-
-    plat = get_platform()
-    if sys.platform == "darwin" and not plat.startswith('macosx-'):
-        try:
-            version = _macosx_vers()
-            machine = os.uname()[4].replace(" ", "_")
-            return "macosx-%d.%d-%s" % (int(version[0]), int(version[1]),
-                _macosx_arch(machine))
-        except ValueError:
-            # if someone is running a non-Mac darwin system, this will fall
-            # through to the default implementation
-            pass
-    return plat
-
-macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)")
-darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)")
-get_platform = get_build_platform   # XXX backward compat
-
-def compatible_platforms(provided,required):
-    """Can code for the `provided` platform run on the `required` platform?
-
-    Returns true if either platform is ``None``, or the platforms are equal.
-
-    XXX Needs compatibility checks for Linux and other unixy OSes.
-    """
-    if provided is None or required is None or provided==required:
-        return True     # easy case
-
-    # Mac OS X special cases
-    reqMac = macosVersionString.match(required)
-    if reqMac:
-        provMac = macosVersionString.match(provided)
-
-        # is this a Mac package?
-        if not provMac:
-            # this is backwards compatibility for packages built before
-            # setuptools 0.6. All packages built after this point will
-            # use the new macosx designation.
-            provDarwin = darwinVersionString.match(provided)
-            if provDarwin:
-                dversion = int(provDarwin.group(1))
-                macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2))
-                if dversion == 7 and macosversion >= "10.3" or \
-                    dversion == 8 and macosversion >= "10.4":
-
-                    #import warnings
-                    #warnings.warn("Mac eggs should be rebuilt to "
-                    #    "use the macosx designation instead of darwin.",
-                    #    category=DeprecationWarning)
-                    return True
-            return False    # egg isn't macosx or legacy darwin
-
-        # are they the same major version and machine type?
-        if provMac.group(1) != reqMac.group(1) or \
-            provMac.group(3) != reqMac.group(3):
-            return False
-
-
-
-        # is the required OS major update >= the provided one?
-        if int(provMac.group(2)) > int(reqMac.group(2)):
-            return False
-
-        return True
-
-    # XXX Linux and other platforms' special cases should go here
-    return False
-
-
-def run_script(dist_spec, script_name):
-    """Locate distribution `dist_spec` and run its `script_name` script"""
-    ns = sys._getframe(1).f_globals
-    name = ns['__name__']
-    ns.clear()
-    ns['__name__'] = name
-    require(dist_spec)[0].run_script(script_name, ns)
-
-run_main = run_script   # backward compatibility
-
-def get_distribution(dist):
-    """Return a current distribution object for a Requirement or string"""
-    if isinstance(dist,str): dist = Requirement.parse(dist)
-    if isinstance(dist,Requirement): dist = get_provider(dist)
-    if not isinstance(dist,Distribution):
-        raise TypeError("Expected string, Requirement, or Distribution", dist)
-    return dist
-
-def load_entry_point(dist, group, name):
-    """Return `name` entry point of `group` for `dist` or raise ImportError"""
-    return get_distribution(dist).load_entry_point(group, name)
-
-def get_entry_map(dist, group=None):
-    """Return the entry point map for `group`, or the full entry map"""
-    return get_distribution(dist).get_entry_map(group)
-
-def get_entry_info(dist, group, name):
-    """Return the EntryPoint object for `group`+`name`, or ``None``"""
-    return get_distribution(dist).get_entry_info(group, name)
-
-
-class IMetadataProvider:
-
-    def has_metadata(name):
-        """Does the package's distribution contain the named metadata?"""
-
-    def get_metadata(name):
-        """The named metadata resource as a string"""
-
-    def get_metadata_lines(name):
-        """Yield named metadata resource as list of non-blank non-comment lines
-
-       Leading and trailing whitespace is stripped from each line, and lines
-       with ``#`` as the first non-blank character are omitted."""
-
-    def metadata_isdir(name):
-        """Is the named metadata a directory?  (like ``os.path.isdir()``)"""
-
-    def metadata_listdir(name):
-        """List of metadata names in the directory (like ``os.listdir()``)"""
-
-    def run_script(script_name, namespace):
-        """Execute the named script in the supplied namespace dictionary"""
-
-
-
-
-
-
-
-
-
-
-class IResourceProvider(IMetadataProvider):
-    """An object that provides access to package resources"""
-
-    def get_resource_filename(manager, resource_name):
-        """Return a true filesystem path for `resource_name`
-
-        `manager` must be an ``IResourceManager``"""
-
-    def get_resource_stream(manager, resource_name):
-        """Return a readable file-like object for `resource_name`
-
-        `manager` must be an ``IResourceManager``"""
-
-    def get_resource_string(manager, resource_name):
-        """Return a string containing the contents of `resource_name`
-
-        `manager` must be an ``IResourceManager``"""
-
-    def has_resource(resource_name):
-        """Does the package contain the named resource?"""
-
-    def resource_isdir(resource_name):
-        """Is the named resource a directory?  (like ``os.path.isdir()``)"""
-
-    def resource_listdir(resource_name):
-        """List of resource names in the directory (like ``os.listdir()``)"""
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class WorkingSet(object):
-    """A collection of active distributions on sys.path (or a similar list)"""
-
-    def __init__(self, entries=None):
-        """Create working set from list of path entries (default=sys.path)"""
-        self.entries = []
-        self.entry_keys = {}
-        self.by_key = {}
-        self.callbacks = []
-
-        if entries is None:
-            entries = sys.path
-
-        for entry in entries:
-            self.add_entry(entry)
-
-
-    def add_entry(self, entry):
-        """Add a path item to ``.entries``, finding any distributions on it
-
-        ``find_distributions(entry,True)`` is used to find distributions
-        corresponding to the path entry, and they are added.  `entry` is
-        always appended to ``.entries``, even if it is already present.
-        (This is because ``sys.path`` can contain the same value more than
-        once, and the ``.entries`` of the ``sys.path`` WorkingSet should always
-        equal ``sys.path``.)
-        """
-        self.entry_keys.setdefault(entry, [])
-        self.entries.append(entry)
-        for dist in find_distributions(entry, True):
-            self.add(dist, entry, False)
-
-
-    def __contains__(self,dist):
-        """True if `dist` is the active distribution for its project"""
-        return self.by_key.get(dist.key) == dist
-
-
-
-
-
-    def find(self, req):
-        """Find a distribution matching requirement `req`
-
-        If there is an active distribution for the requested project, this
-        returns it as long as it meets the version requirement specified by
-        `req`.  But, if there is an active distribution for the project and it
-        does *not* meet the `req` requirement, ``VersionConflict`` is raised.
-        If there is no active distribution for the requested project, ``None``
-        is returned.
-        """
-        dist = self.by_key.get(req.key)
-        if dist is not None and dist not in req:
-            raise VersionConflict(dist,req)     # XXX add more info
-        else:
-            return dist
-
-    def iter_entry_points(self, group, name=None):
-        """Yield entry point objects from `group` matching `name`
-
-        If `name` is None, yields all entry points in `group` from all
-        distributions in the working set, otherwise only ones matching
-        both `group` and `name` are yielded (in distribution order).
-        """
-        for dist in self:
-            entries = dist.get_entry_map(group)
-            if name is None:
-                for ep in list(entries.values()):
-                    yield ep
-            elif name in entries:
-                yield entries[name]
-
-    def run_script(self, requires, script_name):
-        """Locate distribution for `requires` and run `script_name` script"""
-        ns = sys._getframe(1).f_globals
-        name = ns['__name__']
-        ns.clear()
-        ns['__name__'] = name
-        self.require(requires)[0].run_script(script_name, ns)
-
-
-
-    def __iter__(self):
-        """Yield distributions for non-duplicate projects in the working set
-
-        The yield order is the order in which the items' path entries were
-        added to the working set.
-        """
-        seen = {}
-        for item in self.entries:
-            if item not in self.entry_keys:
-                # workaround a cache issue
-                continue
-
-            for key in self.entry_keys[item]:
-                if key not in seen:
-                    seen[key]=1
-                    yield self.by_key[key]
-
-    def add(self, dist, entry=None, insert=True):
-        """Add `dist` to working set, associated with `entry`
-
-        If `entry` is unspecified, it defaults to the ``.location`` of `dist`.
-        On exit from this routine, `entry` is added to the end of the working
-        set's ``.entries`` (if it wasn't already present).
-
-        `dist` is only added to the working set if it's for a project that
-        doesn't already have a distribution in the set.  If it's added, any
-        callbacks registered with the ``subscribe()`` method will be called.
-        """
-        if insert:
-            dist.insert_on(self.entries, entry)
-
-        if entry is None:
-            entry = dist.location
-        keys = self.entry_keys.setdefault(entry,[])
-        keys2 = self.entry_keys.setdefault(dist.location,[])
-        if dist.key in self.by_key:
-            return      # ignore hidden distros
-
-        self.by_key[dist.key] = dist
-        if dist.key not in keys:
-            keys.append(dist.key)
-        if dist.key not in keys2:
-            keys2.append(dist.key)
-        self._added_new(dist)
-
-    def resolve(self, requirements, env=None, installer=None, replacement=True):
-        """List all distributions needed to (recursively) meet `requirements`
-
-        `requirements` must be a sequence of ``Requirement`` objects.  `env`,
-        if supplied, should be an ``Environment`` instance.  If
-        not supplied, it defaults to all distributions available within any
-        entry or distribution in the working set.  `installer`, if supplied,
-        will be invoked with each requirement that cannot be met by an
-        already-installed distribution; it should return a ``Distribution`` or
-        ``None``.
-        """
-
-        requirements = list(requirements)[::-1]  # set up the stack
-        processed = {}  # set of processed requirements
-        best = {}  # key -> dist
-        to_activate = []
-
-        while requirements:
-            req = requirements.pop(0)   # process dependencies breadth-first
-            if _override_setuptools(req) and replacement:
-                req = Requirement.parse('distribute')
-
-            if req in processed:
-                # Ignore cyclic or redundant dependencies
-                continue
-            dist = best.get(req.key)
-            if dist is None:
-                # Find the best distribution and add it to the map
-                dist = self.by_key.get(req.key)
-                if dist is None:
-                    if env is None:
-                        env = Environment(self.entries)
-                    dist = best[req.key] = env.best_match(req, self, installer)
-                    if dist is None:
-                        #msg = ("The '%s' distribution was not found on this "
-                        #       "system, and is required by this application.")
-                        #raise DistributionNotFound(msg % req)
-
-                        # unfortunately, zc.buildout uses a str(err)
-                        # to get the name of the distribution here..
-                        raise DistributionNotFound(req)
-                to_activate.append(dist)
-            if dist not in req:
-                # Oops, the "best" so far conflicts with a dependency
-                raise VersionConflict(dist,req) # XXX put more info here
-            requirements.extend(dist.requires(req.extras)[::-1])
-            processed[req] = True
-
-        return to_activate    # return list of distros to activate
-
-    def find_plugins(self,
-        plugin_env, full_env=None, installer=None, fallback=True
-    ):
-        """Find all activatable distributions in `plugin_env`
-
-        Example usage::
-
-            distributions, errors = working_set.find_plugins(
-                Environment(plugin_dirlist)
-            )
-            map(working_set.add, distributions)  # add plugins+libs to sys.path
-            print 'Could not load', errors        # display errors
-
-        The `plugin_env` should be an ``Environment`` instance that contains
-        only distributions that are in the project's "plugin directory" or
-        directories. The `full_env`, if supplied, should be an ``Environment``
-        contains all currently-available distributions.  If `full_env` is not
-        supplied, one is created automatically from the ``WorkingSet`` this
-        method is called on, which will typically mean that every directory on
-        ``sys.path`` will be scanned for distributions.
-
-        `installer` is a standard installer callback as used by the
-        ``resolve()`` method. The `fallback` flag indicates whether we should
-        attempt to resolve older versions of a plugin if the newest version
-        cannot be resolved.
-
-        This method returns a 2-tuple: (`distributions`, `error_info`), where
-        `distributions` is a list of the distributions found in `plugin_env`
-        that were loadable, along with any other distributions that are needed
-        to resolve their dependencies.  `error_info` is a dictionary mapping
-        unloadable plugin distributions to an exception instance describing the
-        error that occurred. Usually this will be a ``DistributionNotFound`` or
-        ``VersionConflict`` instance.
-        """
-
-        plugin_projects = list(plugin_env)
-        plugin_projects.sort()  # scan project names in alphabetic order
-
-        error_info = {}
-        distributions = {}
-
-        if full_env is None:
-            env = Environment(self.entries)
-            env += plugin_env
-        else:
-            env = full_env + plugin_env
-
-        shadow_set = self.__class__([])
-        list(map(shadow_set.add, self))   # put all our entries in shadow_set
-
-        for project_name in plugin_projects:
-
-            for dist in plugin_env[project_name]:
-
-                req = [dist.as_requirement()]
-
-                try:
-                    resolvees = shadow_set.resolve(req, env, installer)
-
-                except ResolutionError as v:
-                    error_info[dist] = v    # save error info
-                    if fallback:
-                        continue    # try the next older version of project
-                    else:
-                        break       # give up on this project, keep going
-
-                else:
-                    list(map(shadow_set.add, resolvees))
-                    distributions.update(dict.fromkeys(resolvees))
-
-                    # success, no need to try any more versions of this project
-                    break
-
-        distributions = list(distributions)
-        distributions.sort()
-
-        return distributions, error_info
-
-
-
-
-
-    def require(self, *requirements):
-        """Ensure that distributions matching `requirements` are activated
-
-        `requirements` must be a string or a (possibly-nested) sequence
-        thereof, specifying the distributions and versions required.  The
-        return value is a sequence of the distributions that needed to be
-        activated to fulfill the requirements; all relevant distributions are
-        included, even if they were already activated in this working set.
-        """
-
-        needed = self.resolve(parse_requirements(requirements))
-
-        for dist in needed:
-            self.add(dist)
-
-        return needed
-
-
-    def subscribe(self, callback):
-        """Invoke `callback` for all distributions (including existing ones)"""
-        if callback in self.callbacks:
-            return
-        self.callbacks.append(callback)
-        for dist in self:
-            callback(dist)
-
-
-    def _added_new(self, dist):
-        for callback in self.callbacks:
-            callback(dist)
-
-    def __getstate__(self):
-        return (self.entries[:], self.entry_keys.copy(), self.by_key.copy(),
-                self.callbacks[:])
-
-    def __setstate__(self, xxx_todo_changeme):
-        (entries, keys, by_key, callbacks) = xxx_todo_changeme
-        self.entries = entries[:]
-        self.entry_keys = keys.copy()
-        self.by_key = by_key.copy()
-        self.callbacks = callbacks[:]
-
-
-
-
-class Environment(object):
-    """Searchable snapshot of distributions on a search path"""
-
-    def __init__(self, search_path=None, platform=get_supported_platform(), python=PY_MAJOR):
-        """Snapshot distributions available on a search path
-
-        Any distributions found on `search_path` are added to the environment.
-        `search_path` should be a sequence of ``sys.path`` items.  If not
-        supplied, ``sys.path`` is used.
-
-        `platform` is an optional string specifying the name of the platform
-        that platform-specific distributions must be compatible with.  If
-        unspecified, it defaults to the current platform.  `python` is an
-        optional string naming the desired version of Python (e.g. ``'2.4'``);
-        it defaults to the current version.
-
-        You may explicitly set `platform` (and/or `python`) to ``None`` if you
-        wish to map *all* distributions, not just those compatible with the
-        running platform or Python version.
-        """
-        self._distmap = {}
-        self._cache = {}
-        self.platform = platform
-        self.python = python
-        self.scan(search_path)
-
-    def can_add(self, dist):
-        """Is distribution `dist` acceptable for this environment?
-
-        The distribution must match the platform and python version
-        requirements specified when this environment was created, or False
-        is returned.
-        """
-        return (self.python is None or dist.py_version is None
-            or dist.py_version==self.python) \
-           and compatible_platforms(dist.platform,self.platform)
-
-    def remove(self, dist):
-        """Remove `dist` from the environment"""
-        self._distmap[dist.key].remove(dist)
-
-    def scan(self, search_path=None):
-        """Scan `search_path` for distributions usable in this environment
-
-        Any distributions found are added to the environment.
-        `search_path` should be a sequence of ``sys.path`` items.  If not
-        supplied, ``sys.path`` is used.  Only distributions conforming to
-        the platform/python version defined at initialization are added.
-        """
-        if search_path is None:
-            search_path = sys.path
-
-        for item in search_path:
-            for dist in find_distributions(item):
-                self.add(dist)
-
-    def __getitem__(self,project_name):
-        """Return a newest-to-oldest list of distributions for `project_name`
-        """
-        try:
-            return self._cache[project_name]
-        except KeyError:
-            project_name = project_name.lower()
-            if project_name not in self._distmap:
-                return []
-
-        if project_name not in self._cache:
-            dists = self._cache[project_name] = self._distmap[project_name]
-            _sort_dists(dists)
-
-        return self._cache[project_name]
-
-    def add(self,dist):
-        """Add `dist` if we ``can_add()`` it and it isn't already added"""
-        if self.can_add(dist) and dist.has_version():
-            dists = self._distmap.setdefault(dist.key,[])
-            if dist not in dists:
-                dists.append(dist)
-                if dist.key in self._cache:
-                    _sort_dists(self._cache[dist.key])
-
-
-    def best_match(self, req, working_set, installer=None):
-        """Find distribution best matching `req` and usable on `working_set`
-
-        This calls the ``find(req)`` method of the `working_set` to see if a
-        suitable distribution is already active.  (This may raise
-        ``VersionConflict`` if an unsuitable version of the project is already
-        active in the specified `working_set`.)  If a suitable distribution
-        isn't active, this method returns the newest distribution in the
-        environment that meets the ``Requirement`` in `req`.  If no suitable
-        distribution is found, and `installer` is supplied, then the result of
-        calling the environment's ``obtain(req, installer)`` method will be
-        returned.
-        """
-        dist = working_set.find(req)
-        if dist is not None:
-            return dist
-        for dist in self[req.key]:
-            if dist in req:
-                return dist
-        return self.obtain(req, installer) # try and download/install
-
-    def obtain(self, requirement, installer=None):
-        """Obtain a distribution matching `requirement` (e.g. via download)
-
-        Obtain a distro that matches requirement (e.g. via download).  In the
-        base ``Environment`` class, this routine just returns
-        ``installer(requirement)``, unless `installer` is None, in which case
-        None is returned instead.  This method is a hook that allows subclasses
-        to attempt other ways of obtaining a distribution before falling back
-        to the `installer` argument."""
-        if installer is not None:
-            return installer(requirement)
-
-    def __iter__(self):
-        """Yield the unique project names of the available distributions"""
-        for key in list(self._distmap.keys()):
-            if self[key]: yield key
-
-
-
-
-    def __iadd__(self, other):
-        """In-place addition of a distribution or environment"""
-        if isinstance(other,Distribution):
-            self.add(other)
-        elif isinstance(other,Environment):
-            for project in other:
-                for dist in other[project]:
-                    self.add(dist)
-        else:
-            raise TypeError("Can't add %r to environment" % (other,))
-        return self
-
-    def __add__(self, other):
-        """Add an environment or distribution to an environment"""
-        new = self.__class__([], platform=None, python=None)
-        for env in self, other:
-            new += env
-        return new
-
-
-AvailableDistributions = Environment    # XXX backward compatibility
-
-
-class ExtractionError(RuntimeError):
-    """An error occurred extracting a resource
-
-    The following attributes are available from instances of this exception:
-
-    manager
-        The resource manager that raised this exception
-
-    cache_path
-        The base directory for resource extraction
-
-    original_error
-        The exception instance that caused extraction to fail
-    """
-
-
-
-
-class ResourceManager:
-    """Manage resource extraction and packages"""
-    extraction_path = None
-
-    def __init__(self):
-        self.cached_files = {}
-
-    def resource_exists(self, package_or_requirement, resource_name):
-        """Does the named resource exist?"""
-        return get_provider(package_or_requirement).has_resource(resource_name)
-
-    def resource_isdir(self, package_or_requirement, resource_name):
-        """Is the named resource an existing directory?"""
-        return get_provider(package_or_requirement).resource_isdir(
-            resource_name
-        )
-
-    def resource_filename(self, package_or_requirement, resource_name):
-        """Return a true filesystem path for specified resource"""
-        return get_provider(package_or_requirement).get_resource_filename(
-            self, resource_name
-        )
-
-    def resource_stream(self, package_or_requirement, resource_name):
-        """Return a readable file-like object for specified resource"""
-        return get_provider(package_or_requirement).get_resource_stream(
-            self, resource_name
-        )
-
-    def resource_string(self, package_or_requirement, resource_name):
-        """Return specified resource as a string"""
-        return get_provider(package_or_requirement).get_resource_string(
-            self, resource_name
-        )
-
-    def resource_listdir(self, package_or_requirement, resource_name):
-        """List the contents of the named resource directory"""
-        return get_provider(package_or_requirement).resource_listdir(
-            resource_name
-        )
-
-    def extraction_error(self):
-        """Give an error message for problems extracting file(s)"""
-
-        old_exc = sys.exc_info()[1]
-        cache_path = self.extraction_path or get_default_cache()
-
-        err = ExtractionError("""Can't extract file(s) to egg cache
-
-The following error occurred while trying to extract file(s) to the Python egg
-cache:
-
-  %s
-
-The Python egg cache directory is currently set to:
-
-  %s
-
-Perhaps your account does not have write access to this directory?  You can
-change the cache directory by setting the PYTHON_EGG_CACHE environment
-variable to point to an accessible directory.
-"""         % (old_exc, cache_path)
-        )
-        err.manager        = self
-        err.cache_path     = cache_path
-        err.original_error = old_exc
-        raise err
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    def get_cache_path(self, archive_name, names=()):
-        """Return absolute location in cache for `archive_name` and `names`
-
-        The parent directory of the resulting path will be created if it does
-        not already exist.  `archive_name` should be the base filename of the
-        enclosing egg (which may not be the name of the enclosing zipfile!),
-        including its ".egg" extension.  `names`, if provided, should be a
-        sequence of path name parts "under" the egg's extraction location.
-
-        This method should only be called by resource providers that need to
-        obtain an extraction location, and only for names they intend to
-        extract, as it tracks the generated names for possible cleanup later.
-        """
-        extract_path = self.extraction_path or get_default_cache()
-        target_path = os.path.join(extract_path, archive_name+'-tmp', *names)
-        try:
-            _bypass_ensure_directory(target_path)
-        except:
-            self.extraction_error()
-
-        self.cached_files[target_path] = 1
-        return target_path
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    def postprocess(self, tempname, filename):
-        """Perform any platform-specific postprocessing of `tempname`
-
-        This is where Mac header rewrites should be done; other platforms don't
-        have anything special they should do.
-
-        Resource providers should call this method ONLY after successfully
-        extracting a compressed resource.  They must NOT call it on resources
-        that are already in the filesystem.
-
-        `tempname` is the current (temporary) name of the file, and `filename`
-        is the name it will be renamed to by the caller after this routine
-        returns.
-        """
-
-        if os.name == 'posix':
-            # Make the resource executable
-            mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777
-            os.chmod(tempname, mode)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    def set_extraction_path(self, path):
-        """Set the base path where resources will be extracted to, if needed.
-
-        If you do not call this routine before any extractions take place, the
-        path defaults to the return value of ``get_default_cache()``.  (Which
-        is based on the ``PYTHON_EGG_CACHE`` environment variable, with various
-        platform-specific fallbacks.  See that routine's documentation for more
-        details.)
-
-        Resources are extracted to subdirectories of this path based upon
-        information given by the ``IResourceProvider``.  You may set this to a
-        temporary directory, but then you must call ``cleanup_resources()`` to
-        delete the extracted files when done.  There is no guarantee that
-        ``cleanup_resources()`` will be able to remove all extracted files.
-
-        (Note: you may not change the extraction path for a given resource
-        manager once resources have been extracted, unless you first call
-        ``cleanup_resources()``.)
-        """
-        if self.cached_files:
-            raise ValueError(
-                "Can't change extraction path, files already extracted"
-            )
-
-        self.extraction_path = path
-
-    def cleanup_resources(self, force=False):
-        """
-        Delete all extracted resource files and directories, returning a list
-        of the file and directory names that could not be successfully removed.
-        This function does not have any concurrency protection, so it should
-        generally only be called when the extraction path is a temporary
-        directory exclusive to a single process.  This method is not
-        automatically called; you must call it explicitly or register it as an
-        ``atexit`` function if you wish to ensure cleanup of a temporary
-        directory used for extractions.
-        """
-        # XXX
-
-
-
-def get_default_cache():
-    """Determine the default cache location
-
-    This returns the ``PYTHON_EGG_CACHE`` environment variable, if set.
-    Otherwise, on Windows, it returns a "Python-Eggs" subdirectory of the
-    "Application Data" directory.  On all other systems, it's "~/.python-eggs".
-    """
-    try:
-        return os.environ['PYTHON_EGG_CACHE']
-    except KeyError:
-        pass
-
-    if os.name!='nt':
-        return os.path.expanduser('~/.python-eggs')
-
-    app_data = 'Application Data'   # XXX this may be locale-specific!
-    app_homes = [
-        (('APPDATA',), None),       # best option, should be locale-safe
-        (('USERPROFILE',), app_data),
-        (('HOMEDRIVE','HOMEPATH'), app_data),
-        (('HOMEPATH',), app_data),
-        (('HOME',), None),
-        (('WINDIR',), app_data),    # 95/98/ME
-    ]
-
-    for keys, subdir in app_homes:
-        dirname = ''
-        for key in keys:
-            if key in os.environ:
-                dirname = os.path.join(dirname, os.environ[key])
-            else:
-                break
-        else:
-            if subdir:
-                dirname = os.path.join(dirname,subdir)
-            return os.path.join(dirname, 'Python-Eggs')
-    else:
-        raise RuntimeError(
-            "Please set the PYTHON_EGG_CACHE enviroment variable"
-        )
-
-def safe_name(name):
-    """Convert an arbitrary string to a standard distribution name
-
-    Any runs of non-alphanumeric/. characters are replaced with a single '-'.
-    """
-    return re.sub('[^A-Za-z0-9.]+', '-', name)
-
-
-def safe_version(version):
-    """Convert an arbitrary string to a standard version string
-
-    Spaces become dots, and all other non-alphanumeric characters become
-    dashes, with runs of multiple dashes condensed to a single dash.
-    """
-    version = version.replace(' ','.')
-    return re.sub('[^A-Za-z0-9.]+', '-', version)
-
-
-def safe_extra(extra):
-    """Convert an arbitrary string to a standard 'extra' name
-
-    Any runs of non-alphanumeric characters are replaced with a single '_',
-    and the result is always lowercased.
-    """
-    return re.sub('[^A-Za-z0-9.]+', '_', extra).lower()
-
-
-def to_filename(name):
-    """Convert a project or version name to its filename-escaped form
-
-    Any '-' characters are currently replaced with '_'.
-    """
-    return name.replace('-','_')
-
-
-
-
-
-
-
-
-class NullProvider:
-    """Try to implement resources and metadata for arbitrary PEP 302 loaders"""
-
-    egg_name = None
-    egg_info = None
-    loader = None
-
-    def __init__(self, module):
-        self.loader = getattr(module, '__loader__', None)
-        self.module_path = os.path.dirname(getattr(module, '__file__', ''))
-
-    def get_resource_filename(self, manager, resource_name):
-        return self._fn(self.module_path, resource_name)
-
-    def get_resource_stream(self, manager, resource_name):
-        return StringIO(self.get_resource_string(manager, resource_name))
-
-    def get_resource_string(self, manager, resource_name):
-        return self._get(self._fn(self.module_path, resource_name))
-
-    def has_resource(self, resource_name):
-        return self._has(self._fn(self.module_path, resource_name))
-
-    def has_metadata(self, name):
-        return self.egg_info and self._has(self._fn(self.egg_info,name))
-
-    if sys.version_info <= (3,):
-        def get_metadata(self, name):
-            if not self.egg_info:
-                return ""
-            return self._get(self._fn(self.egg_info,name))
-    else:
-        def get_metadata(self, name):
-            if not self.egg_info:
-                return ""
-            return self._get(self._fn(self.egg_info,name)).decode("utf-8")
-
-    def get_metadata_lines(self, name):
-        return yield_lines(self.get_metadata(name))
-
-    def resource_isdir(self,resource_name):
-        return self._isdir(self._fn(self.module_path, resource_name))
-
-    def metadata_isdir(self,name):
-        return self.egg_info and self._isdir(self._fn(self.egg_info,name))
-
-
-    def resource_listdir(self,resource_name):
-        return self._listdir(self._fn(self.module_path,resource_name))
-
-    def metadata_listdir(self,name):
-        if self.egg_info:
-            return self._listdir(self._fn(self.egg_info,name))
-        return []
-
-    def run_script(self,script_name,namespace):
-        script = 'scripts/'+script_name
-        if not self.has_metadata(script):
-            raise ResolutionError("No script named %r" % script_name)
-        script_text = self.get_metadata(script).replace('\r\n','\n')
-        script_text = script_text.replace('\r','\n')
-        script_filename = self._fn(self.egg_info,script)
-        namespace['__file__'] = script_filename
-        if os.path.exists(script_filename):
-            exec(compile(open(script_filename).read(), script_filename, 'exec'), namespace, namespace)
-        else:
-            from linecache import cache
-            cache[script_filename] = (
-                len(script_text), 0, script_text.split('\n'), script_filename
-            )
-            script_code = compile(script_text,script_filename,'exec')
-            exec(script_code, namespace, namespace)
-
-    def _has(self, path):
-        raise NotImplementedError(
-            "Can't perform this operation for unregistered loader type"
-        )
-
-    def _isdir(self, path):
-        raise NotImplementedError(
-            "Can't perform this operation for unregistered loader type"
-        )
-
-    def _listdir(self, path):
-        raise NotImplementedError(
-            "Can't perform this operation for unregistered loader type"
-        )
-
-    def _fn(self, base, resource_name):
-        if resource_name:
-            return os.path.join(base, *resource_name.split('/'))
-        return base
-
-    def _get(self, path):
-        if hasattr(self.loader, 'get_data'):
-            return self.loader.get_data(path)
-        raise NotImplementedError(
-            "Can't perform this operation for loaders without 'get_data()'"
-        )
-
-register_loader_type(object, NullProvider)
-
-
-class EggProvider(NullProvider):
-    """Provider based on a virtual filesystem"""
-
-    def __init__(self,module):
-        NullProvider.__init__(self,module)
-        self._setup_prefix()
-
-    def _setup_prefix(self):
-        # we assume here that our metadata may be nested inside a "basket"
-        # of multiple eggs; that's why we use module_path instead of .archive
-        path = self.module_path
-        old = None
-        while path!=old:
-            if path.lower().endswith('.egg'):
-                self.egg_name = os.path.basename(path)
-                self.egg_info = os.path.join(path, 'EGG-INFO')
-                self.egg_root = path
-                break
-            old = path
-            path, base = os.path.split(path)
-
-
-
-
-
-
-class DefaultProvider(EggProvider):
-    """Provides access to package resources in the filesystem"""
-
-    def _has(self, path):
-        return os.path.exists(path)
-
-    def _isdir(self,path):
-        return os.path.isdir(path)
-
-    def _listdir(self,path):
-        return os.listdir(path)
-
-    def get_resource_stream(self, manager, resource_name):
-        return open(self._fn(self.module_path, resource_name), 'rb')
-
-    def _get(self, path):
-        stream = open(path, 'rb')
-        try:
-            return stream.read()
-        finally:
-            stream.close()
-
-register_loader_type(type(None), DefaultProvider)
-
-try:
-    # CPython >=3.3
-    import _frozen_importlib
-except ImportError:
-    pass
-else:
-    register_loader_type(_frozen_importlib.SourceFileLoader, DefaultProvider)
-
-
-class EmptyProvider(NullProvider):
-    """Provider that returns nothing for all requests"""
-
-    _isdir = _has = lambda self,path: False
-    _get          = lambda self,path: ''
-    _listdir      = lambda self,path: []
-    module_path   = None
-
-    def __init__(self):
-        pass
-
-empty_provider = EmptyProvider()
-
-
-
-
-class ZipProvider(EggProvider):
-    """Resource support for zips and eggs"""
-
-    eagers = None
-
-    def __init__(self, module):
-        EggProvider.__init__(self,module)
-        self.zipinfo = zipimport._zip_directory_cache[self.loader.archive]
-        self.zip_pre = self.loader.archive+os.sep
-
-    def _zipinfo_name(self, fspath):
-        # Convert a virtual filename (full path to file) into a zipfile subpath
-        # usable with the zipimport directory cache for our target archive
-        if fspath.startswith(self.zip_pre):
-            return fspath[len(self.zip_pre):]
-        raise AssertionError(
-            "%s is not a subpath of %s" % (fspath,self.zip_pre)
-        )
-
-    def _parts(self,zip_path):
-        # Convert a zipfile subpath into an egg-relative path part list
-        fspath = self.zip_pre+zip_path  # pseudo-fs path
-        if fspath.startswith(self.egg_root+os.sep):
-            return fspath[len(self.egg_root)+1:].split(os.sep)
-        raise AssertionError(
-            "%s is not a subpath of %s" % (fspath,self.egg_root)
-        )
-
-    def get_resource_filename(self, manager, resource_name):
-        if not self.egg_name:
-            raise NotImplementedError(
-                "resource_filename() only supported for .egg, not .zip"
-            )
-        # no need to lock for extraction, since we use temp names
-        zip_path = self._resource_to_zip(resource_name)
-        eagers = self._get_eager_resources()
-        if '/'.join(self._parts(zip_path)) in eagers:
-            for name in eagers:
-                self._extract_resource(manager, self._eager_to_zip(name))
-        return self._extract_resource(manager, zip_path)
-
-    def _extract_resource(self, manager, zip_path):
-
-        if zip_path in self._index():
-            for name in self._index()[zip_path]:
-                last = self._extract_resource(
-                    manager, os.path.join(zip_path, name)
-                )
-            return os.path.dirname(last)  # return the extracted directory name
-
-        zip_stat = self.zipinfo[zip_path]
-        t,d,size = zip_stat[5], zip_stat[6], zip_stat[3]
-        date_time = (
-            (d>>9)+1980, (d>>5)&0xF, d&0x1F,                      # ymd
-            (t&0xFFFF)>>11, (t>>5)&0x3F, (t&0x1F) * 2, 0, 0, -1   # hms, etc.
-        )
-        timestamp = time.mktime(date_time)
-
-        try:
-            if not WRITE_SUPPORT:
-                raise IOError('"os.rename" and "os.unlink" are not supported '
-                              'on this platform')
-
-            real_path = manager.get_cache_path(
-                self.egg_name, self._parts(zip_path)
-            )
-
-            if os.path.isfile(real_path):
-                stat = os.stat(real_path)
-                if stat.st_size==size and stat.st_mtime==timestamp:
-                    # size and stamp match, don't bother extracting
-                    return real_path
-
-            outf, tmpnam = _mkstemp(".$extract", dir=os.path.dirname(real_path))
-            os.write(outf, self.loader.get_data(zip_path))
-            os.close(outf)
-            utime(tmpnam, (timestamp,timestamp))
-            manager.postprocess(tmpnam, real_path)
-
-            try:
-                rename(tmpnam, real_path)
-
-            except os.error:
-                if os.path.isfile(real_path):
-                    stat = os.stat(real_path)
-
-                    if stat.st_size==size and stat.st_mtime==timestamp:
-                        # size and stamp match, somebody did it just ahead of
-                        # us, so we're done
-                        return real_path
-                    elif os.name=='nt':     # Windows, del old file and retry
-                        unlink(real_path)
-                        rename(tmpnam, real_path)
-                        return real_path
-                raise
-
-        except os.error:
-            manager.extraction_error()  # report a user-friendly error
-
-        return real_path
-
-    def _get_eager_resources(self):
-        if self.eagers is None:
-            eagers = []
-            for name in ('native_libs.txt', 'eager_resources.txt'):
-                if self.has_metadata(name):
-                    eagers.extend(self.get_metadata_lines(name))
-            self.eagers = eagers
-        return self.eagers
-
-    def _index(self):
-        try:
-            return self._dirindex
-        except AttributeError:
-            ind = {}
-            for path in self.zipinfo:
-                parts = path.split(os.sep)
-                while parts:
-                    parent = os.sep.join(parts[:-1])
-                    if parent in ind:
-                        ind[parent].append(parts[-1])
-                        break
-                    else:
-                        ind[parent] = [parts.pop()]
-            self._dirindex = ind
-            return ind
-
-    def _has(self, fspath):
-        zip_path = self._zipinfo_name(fspath)
-        return zip_path in self.zipinfo or zip_path in self._index()
-
-    def _isdir(self,fspath):
-        return self._zipinfo_name(fspath) in self._index()
-
-    def _listdir(self,fspath):
-        return list(self._index().get(self._zipinfo_name(fspath), ()))
-
-    def _eager_to_zip(self,resource_name):
-        return self._zipinfo_name(self._fn(self.egg_root,resource_name))
-
-    def _resource_to_zip(self,resource_name):
-        return self._zipinfo_name(self._fn(self.module_path,resource_name))
-
-register_loader_type(zipimport.zipimporter, ZipProvider)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class FileMetadata(EmptyProvider):
-    """Metadata handler for standalone PKG-INFO files
-
-    Usage::
-
-        metadata = FileMetadata("/path/to/PKG-INFO")
-
-    This provider rejects all data and metadata requests except for PKG-INFO,
-    which is treated as existing, and will be the contents of the file at
-    the provided location.
-    """
-
-    def __init__(self,path):
-        self.path = path
-
-    def has_metadata(self,name):
-        return name=='PKG-INFO'
-
-    def get_metadata(self,name):
-        if name=='PKG-INFO':
-            f = open(self.path,'rU')
-            metadata = f.read()
-            f.close()
-            return metadata
-        raise KeyError("No metadata except PKG-INFO is available")
-
-    def get_metadata_lines(self,name):
-        return yield_lines(self.get_metadata(name))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class PathMetadata(DefaultProvider):
-    """Metadata provider for egg directories
-
-    Usage::
-
-        # Development eggs:
-
-        egg_info = "/path/to/PackageName.egg-info"
-        base_dir = os.path.dirname(egg_info)
-        metadata = PathMetadata(base_dir, egg_info)
-        dist_name = os.path.splitext(os.path.basename(egg_info))[0]
-        dist = Distribution(basedir,project_name=dist_name,metadata=metadata)
-
-        # Unpacked egg directories:
-
-        egg_path = "/path/to/PackageName-ver-pyver-etc.egg"
-        metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO'))
-        dist = Distribution.from_filename(egg_path, metadata=metadata)
-    """
-
-    def __init__(self, path, egg_info):
-        self.module_path = path
-        self.egg_info = egg_info
-
-
-class EggMetadata(ZipProvider):
-    """Metadata provider for .egg files"""
-
-    def __init__(self, importer):
-        """Create a metadata provider from a zipimporter"""
-
-        self.zipinfo = zipimport._zip_directory_cache[importer.archive]
-        self.zip_pre = importer.archive+os.sep
-        self.loader = importer
-        if importer.prefix:
-            self.module_path = os.path.join(importer.archive, importer.prefix)
-        else:
-            self.module_path = importer.archive
-        self._setup_prefix()
-
-
-class ImpWrapper:
-    """PEP 302 Importer that wraps Python's "normal" import algorithm"""
-
-    def __init__(self, path=None):
-        self.path = path
-
-    def find_module(self, fullname, path=None):
-        subname = fullname.split(".")[-1]
-        if subname != fullname and self.path is None:
-            return None
-        if self.path is None:
-            path = None
-        else:
-            path = [self.path]
-        try:
-            file, filename, etc = imp.find_module(subname, path)
-        except ImportError:
-            return None
-        return ImpLoader(file, filename, etc)
-
-
-class ImpLoader:
-    """PEP 302 Loader that wraps Python's "normal" import algorithm"""
-
-    def __init__(self, file, filename, etc):
-        self.file = file
-        self.filename = filename
-        self.etc = etc
-
-    def load_module(self, fullname):
-        try:
-            mod = imp.load_module(fullname, self.file, self.filename, self.etc)
-        finally:
-            if self.file: self.file.close()
-        # Note: we don't set __loader__ because we want the module to look
-        # normal; i.e. this is just a wrapper for standard import machinery
-        return mod
-
-
-
-
-def get_importer(path_item):
-    """Retrieve a PEP 302 "importer" for the given path item
-
-    If there is no importer, this returns a wrapper around the builtin import
-    machinery.  The returned importer is only cached if it was created by a
-    path hook.
-    """
-    try:
-        importer = sys.path_importer_cache[path_item]
-    except KeyError:
-        for hook in sys.path_hooks:
-            try:
-                importer = hook(path_item)
-            except ImportError:
-                pass
-            else:
-                break
-        else:
-            importer = None
-
-    sys.path_importer_cache.setdefault(path_item,importer)
-    if importer is None:
-        try:
-            importer = ImpWrapper(path_item)
-        except ImportError:
-            pass
-    return importer
-
-try:
-    from pkgutil import get_importer, ImpImporter
-except ImportError:
-    pass    # Python 2.3 or 2.4, use our own implementation
-else:
-    ImpWrapper = ImpImporter    # Python 2.5, use pkgutil's implementation
-    del ImpLoader, ImpImporter
-
-
-
-
-
-
-_declare_state('dict', _distribution_finders = {})
-
-def register_finder(importer_type, distribution_finder):
-    """Register `distribution_finder` to find distributions in sys.path items
-
-    `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item
-    handler), and `distribution_finder` is a callable that, passed a path
-    item and the importer instance, yields ``Distribution`` instances found on
-    that path item.  See ``pkg_resources.find_on_path`` for an example."""
-    _distribution_finders[importer_type] = distribution_finder
-
-
-def find_distributions(path_item, only=False):
-    """Yield distributions accessible via `path_item`"""
-    importer = get_importer(path_item)
-    finder = _find_adapter(_distribution_finders, importer)
-    return finder(importer, path_item, only)
-
-def find_in_zip(importer, path_item, only=False):
-    metadata = EggMetadata(importer)
-    if metadata.has_metadata('PKG-INFO'):
-        yield Distribution.from_filename(path_item, metadata=metadata)
-    if only:
-        return  # don't yield nested distros
-    for subitem in metadata.resource_listdir('/'):
-        if subitem.endswith('.egg'):
-            subpath = os.path.join(path_item, subitem)
-            for dist in find_in_zip(zipimport.zipimporter(subpath), subpath):
-                yield dist
-
-register_finder(zipimport.zipimporter, find_in_zip)
-
-def StringIO(*args, **kw):
-    """Thunk to load the real StringIO on demand"""
-    global StringIO
-    try:
-        from io import StringIO
-    except ImportError:
-        from io import StringIO
-    return StringIO(*args,**kw)
-
-def find_nothing(importer, path_item, only=False):
-    return ()
-register_finder(object,find_nothing)
-
-def find_on_path(importer, path_item, only=False):
-    """Yield distributions accessible on a sys.path directory"""
-    path_item = _normalize_cached(path_item)
-
-    if os.path.isdir(path_item) and os.access(path_item, os.R_OK):
-        if path_item.lower().endswith('.egg'):
-            # unpacked egg
-            yield Distribution.from_filename(
-                path_item, metadata=PathMetadata(
-                    path_item, os.path.join(path_item,'EGG-INFO')
-                )
-            )
-        else:
-            # scan for .egg and .egg-info in directory
-            for entry in os.listdir(path_item):
-                lower = entry.lower()
-                if lower.endswith('.egg-info') or lower.endswith('.dist-info'):
-                    fullpath = os.path.join(path_item, entry)
-                    if os.path.isdir(fullpath):
-                        # egg-info directory, allow getting metadata
-                        metadata = PathMetadata(path_item, fullpath)
-                    else:
-                        metadata = FileMetadata(fullpath)
-                    yield Distribution.from_location(
-                        path_item,entry,metadata,precedence=DEVELOP_DIST
-                    )
-                elif not only and lower.endswith('.egg'):
-                    for dist in find_distributions(os.path.join(path_item, entry)):
-                        yield dist
-                elif not only and lower.endswith('.egg-link'):
-                    for line in open(os.path.join(path_item, entry)):
-                        if not line.strip(): continue
-                        for item in find_distributions(os.path.join(path_item,line.rstrip())):
-                            yield item
-                        break
-register_finder(ImpWrapper,find_on_path)
-
-try:
-    # CPython >=3.3
-    import _frozen_importlib
-except ImportError:
-    pass
-else:
-    register_finder(_frozen_importlib.FileFinder, find_on_path)
-
-_declare_state('dict', _namespace_handlers={})
-_declare_state('dict', _namespace_packages={})
-
-
-def register_namespace_handler(importer_type, namespace_handler):
-    """Register `namespace_handler` to declare namespace packages
-
-    `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item
-    handler), and `namespace_handler` is a callable like this::
-
-        def namespace_handler(importer,path_entry,moduleName,module):
-            # return a path_entry to use for child packages
-
-    Namespace handlers are only called if the importer object has already
-    agreed that it can handle the relevant path item, and they should only
-    return a subpath if the module __path__ does not already contain an
-    equivalent subpath.  For an example namespace handler, see
-    ``pkg_resources.file_ns_handler``.
-    """
-    _namespace_handlers[importer_type] = namespace_handler
-
-def _handle_ns(packageName, path_item):
-    """Ensure that named package includes a subpath of path_item (if needed)"""
-    importer = get_importer(path_item)
-    if importer is None:
-        return None
-    loader = importer.find_module(packageName)
-    if loader is None:
-        return None
-    module = sys.modules.get(packageName)
-    if module is None:
-        module = sys.modules[packageName] = types.ModuleType(packageName)
-        module.__path__ = []; _set_parent_ns(packageName)
-    elif not hasattr(module,'__path__'):
-        raise TypeError("Not a package:", packageName)
-    handler = _find_adapter(_namespace_handlers, importer)
-    subpath = handler(importer,path_item,packageName,module)
-    if subpath is not None:
-        path = module.__path__; path.append(subpath)
-        loader.load_module(packageName); module.__path__ = path
-    return subpath
-
-def declare_namespace(packageName):
-    """Declare that package 'packageName' is a namespace package"""
-
-    imp.acquire_lock()
-    try:
-        if packageName in _namespace_packages:
-            return
-
-        path, parent = sys.path, None
-        if '.' in packageName:
-            parent = '.'.join(packageName.split('.')[:-1])
-            declare_namespace(parent)
-            if parent not in _namespace_packages:
-                __import__(parent)
-            try:
-                path = sys.modules[parent].__path__
-            except AttributeError:
-                raise TypeError("Not a package:", parent)
-
-        # Track what packages are namespaces, so when new path items are added,
-        # they can be updated
-        _namespace_packages.setdefault(parent,[]).append(packageName)
-        _namespace_packages.setdefault(packageName,[])
-
-        for path_item in path:
-            # Ensure all the parent's path items are reflected in the child,
-            # if they apply
-            _handle_ns(packageName, path_item)
-
-    finally:
-        imp.release_lock()
-
-def fixup_namespace_packages(path_item, parent=None):
-    """Ensure that previously-declared namespace packages include path_item"""
-    imp.acquire_lock()
-    try:
-        for package in _namespace_packages.get(parent,()):
-            subpath = _handle_ns(package, path_item)
-            if subpath: fixup_namespace_packages(subpath,package)
-    finally:
-        imp.release_lock()
-
-def file_ns_handler(importer, path_item, packageName, module):
-    """Compute an ns-package subpath for a filesystem or zipfile importer"""
-
-    subpath = os.path.join(path_item, packageName.split('.')[-1])
-    normalized = _normalize_cached(subpath)
-    for item in module.__path__:
-        if _normalize_cached(item)==normalized:
-            break
-    else:
-        # Only return the path if it's not already there
-        return subpath
-
-register_namespace_handler(ImpWrapper,file_ns_handler)
-register_namespace_handler(zipimport.zipimporter,file_ns_handler)
-
-try:
-    # CPython >=3.3
-    import _frozen_importlib
-except ImportError:
-    pass
-else:
-    register_namespace_handler(_frozen_importlib.FileFinder, file_ns_handler)
-
-
-def null_ns_handler(importer, path_item, packageName, module):
-    return None
-
-register_namespace_handler(object,null_ns_handler)
-
-
-def normalize_path(filename):
-    """Normalize a file/dir name for comparison purposes"""
-    return os.path.normcase(os.path.realpath(filename))
-
-def _normalize_cached(filename,_cache={}):
-    try:
-        return _cache[filename]
-    except KeyError:
-        _cache[filename] = result = normalize_path(filename)
-        return result
-
-def _set_parent_ns(packageName):
-    parts = packageName.split('.')
-    name = parts.pop()
-    if parts:
-        parent = '.'.join(parts)
-        setattr(sys.modules[parent], name, sys.modules[packageName])
-
-
-def yield_lines(strs):
-    """Yield non-empty/non-comment lines of a ``basestring`` or sequence"""
-    if isinstance(strs,str):
-        for s in strs.splitlines():
-            s = s.strip()
-            if s and not s.startswith('#'):     # skip blank lines/comments
-                yield s
-    else:
-        for ss in strs:
-            for s in yield_lines(ss):
-                yield s
-
-LINE_END = re.compile(r"\s*(#.*)?$").match         # whitespace and comment
-CONTINUE = re.compile(r"\s*\\\s*(#.*)?$").match    # line continuation
-DISTRO   = re.compile(r"\s*((\w|[-.])+)").match    # Distribution or extra
-VERSION  = re.compile(r"\s*(<=?|>=?|==|!=)\s*((\w|[-.])+)").match  # ver. info
-COMMA    = re.compile(r"\s*,").match               # comma between items
-OBRACKET = re.compile(r"\s*\[").match
-CBRACKET = re.compile(r"\s*\]").match
-MODULE   = re.compile(r"\w+(\.\w+)*$").match
-EGG_NAME = re.compile(
-    r"(?P<name>[^-]+)"
-    r"( -(?P<ver>[^-]+) (-py(?P<pyver>[^-]+) (-(?P<plat>.+))? )? )?",
-    re.VERBOSE | re.IGNORECASE
-).match
-
-component_re = re.compile(r'(\d+ | [a-z]+ | \.| -)', re.VERBOSE)
-replace = {'pre':'c', 'preview':'c','-':'final-','rc':'c','dev':'@'}.get
-
-def _parse_version_parts(s):
-    for part in component_re.split(s):
-        part = replace(part,part)
-        if part in ['', '.']:
-            continue
-        if part[:1] in '0123456789':
-            yield part.zfill(8)    # pad for numeric comparison
-        else:
-            yield '*'+part
-
-    yield '*final'  # ensure that alpha/beta/candidate are before final
-
-def parse_version(s):
-    """Convert a version string to a chronologically-sortable key
-
-    This is a rough cross between distutils' StrictVersion and LooseVersion;
-    if you give it versions that would work with StrictVersion, then it behaves
-    the same; otherwise it acts like a slightly-smarter LooseVersion. It is
-    *possible* to create pathological version coding schemes that will fool
-    this parser, but they should be very rare in practice.
-
-    The returned value will be a tuple of strings.  Numeric portions of the
-    version are padded to 8 digits so they will compare numerically, but
-    without relying on how numbers compare relative to strings.  Dots are
-    dropped, but dashes are retained.  Trailing zeros between alpha segments
-    or dashes are suppressed, so that e.g. "2.4.0" is considered the same as
-    "2.4". Alphanumeric parts are lower-cased.
-
-    The algorithm assumes that strings like "-" and any alpha string that
-    alphabetically follows "final"  represents a "patch level".  So, "2.4-1"
-    is assumed to be a branch or patch of "2.4", and therefore "2.4.1" is
-    considered newer than "2.4-1", which in turn is newer than "2.4".
-
-    Strings like "a", "b", "c", "alpha", "beta", "candidate" and so on (that
-    come before "final" alphabetically) are assumed to be pre-release versions,
-    so that the version "2.4" is considered newer than "2.4a1".
-
-    Finally, to handle miscellaneous cases, the strings "pre", "preview", and
-    "rc" are treated as if they were "c", i.e. as though they were release
-    candidates, and therefore are not as new as a version string that does not
-    contain them, and "dev" is replaced with an '@' so that it sorts lower than
-    than any other pre-release tag.
-    """
-    parts = []
-    for part in _parse_version_parts(s.lower()):
-        if part.startswith('*'):
-            # remove trailing zeros from each series of numeric parts
-            while parts and parts[-1]=='00000000':
-                parts.pop()
-        parts.append(part)
-    return tuple(parts)
-
-class EntryPoint(object):
-    """Object representing an advertised importable object"""
-
-    def __init__(self, name, module_name, attrs=(), extras=(), dist=None):
-        if not MODULE(module_name):
-            raise ValueError("Invalid module name", module_name)
-        self.name = name
-        self.module_name = module_name
-        self.attrs = tuple(attrs)
-        self.extras = Requirement.parse(("x[%s]" % ','.join(extras))).extras
-        self.dist = dist
-
-    def __str__(self):
-        s = "%s = %s" % (self.name, self.module_name)
-        if self.attrs:
-            s += ':' + '.'.join(self.attrs)
-        if self.extras:
-            s += ' [%s]' % ','.join(self.extras)
-        return s
-
-    def __repr__(self):
-        return "EntryPoint.parse(%r)" % str(self)
-
-    def load(self, require=True, env=None, installer=None):
-        if require: self.require(env, installer)
-        entry = __import__(self.module_name, globals(),globals(), ['__name__'])
-        for attr in self.attrs:
-            try:
-                entry = getattr(entry,attr)
-            except AttributeError:
-                raise ImportError("%r has no %r attribute" % (entry,attr))
-        return entry
-
-    def require(self, env=None, installer=None):
-        if self.extras and not self.dist:
-            raise UnknownExtra("Can't require() without a distribution", self)
-        list(map(working_set.add,
-            working_set.resolve(self.dist.requires(self.extras),env,installer)))
-
-
-
-    #@classmethod
-    def parse(cls, src, dist=None):
-        """Parse a single entry point from string `src`
-
-        Entry point syntax follows the form::
-
-            name = some.module:some.attr [extra1,extra2]
-
-        The entry name and module name are required, but the ``:attrs`` and
-        ``[extras]`` parts are optional
-        """
-        try:
-            attrs = extras = ()
-            name,value = src.split('=',1)
-            if '[' in value:
-                value,extras = value.split('[',1)
-                req = Requirement.parse("x["+extras)
-                if req.specs: raise ValueError
-                extras = req.extras
-            if ':' in value:
-                value,attrs = value.split(':',1)
-                if not MODULE(attrs.rstrip()):
-                    raise ValueError
-                attrs = attrs.rstrip().split('.')
-        except ValueError:
-            raise ValueError(
-                "EntryPoint must be in 'name=module:attrs [extras]' format",
-                src
-            )
-        else:
-            return cls(name.strip(), value.strip(), attrs, extras, dist)
-
-    parse = classmethod(parse)
-
-
-
-
-
-
-
-
-    #@classmethod
-    def parse_group(cls, group, lines, dist=None):
-        """Parse an entry point group"""
-        if not MODULE(group):
-            raise ValueError("Invalid group name", group)
-        this = {}
-        for line in yield_lines(lines):
-            ep = cls.parse(line, dist)
-            if ep.name in this:
-                raise ValueError("Duplicate entry point", group, ep.name)
-            this[ep.name]=ep
-        return this
-
-    parse_group = classmethod(parse_group)
-
-    #@classmethod
-    def parse_map(cls, data, dist=None):
-        """Parse a map of entry point groups"""
-        if isinstance(data,dict):
-            data = list(data.items())
-        else:
-            data = split_sections(data)
-        maps = {}
-        for group, lines in data:
-            if group is None:
-                if not lines:
-                    continue
-                raise ValueError("Entry points must be listed in groups")
-            group = group.strip()
-            if group in maps:
-                raise ValueError("Duplicate group name", group)
-            maps[group] = cls.parse_group(group, lines, dist)
-        return maps
-
-    parse_map = classmethod(parse_map)
-
-
-def _remove_md5_fragment(location):
-    if not location:
-        return ''
-    parsed = urlparse(location)
-    if parsed[-1].startswith('md5='):
-        return urlunparse(parsed[:-1] + ('',))
-    return location
-
-
-class Distribution(object):
-    """Wrap an actual or potential sys.path entry w/metadata"""
-    PKG_INFO = 'PKG-INFO'
-    
-    def __init__(self,
-        location=None, metadata=None, project_name=None, version=None,
-        py_version=PY_MAJOR, platform=None, precedence = EGG_DIST
-    ):
-        self.project_name = safe_name(project_name or 'Unknown')
-        if version is not None:
-            self._version = safe_version(version)
-        self.py_version = py_version
-        self.platform = platform
-        self.location = location
-        self.precedence = precedence
-        self._provider = metadata or empty_provider
-
-    #@classmethod
-    def from_location(cls,location,basename,metadata=None,**kw):
-        project_name, version, py_version, platform = [None]*4
-        basename, ext = os.path.splitext(basename)
-        if ext.lower() in _distributionImpl:
-            # .dist-info gets much metadata differently
-            match = EGG_NAME(basename)
-            if match:
-                project_name, version, py_version, platform = match.group(
-                    'name','ver','pyver','plat'
-                )
-            cls = _distributionImpl[ext.lower()]
-        return cls(
-            location, metadata, project_name=project_name, version=version,
-            py_version=py_version, platform=platform, **kw
-        )
-    from_location = classmethod(from_location)
-
-
-    hashcmp = property(
-        lambda self: (
-            getattr(self,'parsed_version',()),
-            self.precedence,
-            self.key,
-            _remove_md5_fragment(self.location),
-            self.py_version,
-            self.platform
-        )
-    )
-    def __hash__(self): return hash(self.hashcmp)
-    def __lt__(self, other):
-        return self.hashcmp < other.hashcmp
-    def __le__(self, other):
-        return self.hashcmp <= other.hashcmp
-    def __gt__(self, other):
-        return self.hashcmp > other.hashcmp
-    def __ge__(self, other):
-        return self.hashcmp >= other.hashcmp
-    def __eq__(self, other):
-        if not isinstance(other, self.__class__):
-            # It's not a Distribution, so they are not equal
-            return False
-        return self.hashcmp == other.hashcmp
-    def __ne__(self, other):
-        return not self == other
-
-    # These properties have to be lazy so that we don't have to load any
-    # metadata until/unless it's actually needed.  (i.e., some distributions
-    # may not know their name or version without loading PKG-INFO)
-
-    #@property
-    def key(self):
-        try:
-            return self._key
-        except AttributeError:
-            self._key = key = self.project_name.lower()
-            return key
-    key = property(key)
-
-    #@property
-    def parsed_version(self):
-        try:
-            return self._parsed_version
-        except AttributeError:
-            self._parsed_version = pv = parse_version(self.version)
-            return pv
-
-    parsed_version = property(parsed_version)
-
-    #@property
-    def version(self):
-        try:
-            return self._version
-        except AttributeError:
-            for line in self._get_metadata(self.PKG_INFO):
-                if line.lower().startswith('version:'):
-                    self._version = safe_version(line.split(':',1)[1].strip())
-                    return self._version
-            else:
-                raise ValueError(
-                    "Missing 'Version:' header and/or %s file" % self.PKG_INFO, self
-                )
-    version = property(version)
-
-
-
-
-    #@property
-    def _dep_map(self):
-        try:
-            return self.__dep_map
-        except AttributeError:
-            dm = self.__dep_map = {None: []}
-            for name in 'requires.txt', 'depends.txt':
-                for extra,reqs in split_sections(self._get_metadata(name)):
-                    if extra: extra = safe_extra(extra)
-                    dm.setdefault(extra,[]).extend(parse_requirements(reqs))
-            return dm
-    _dep_map = property(_dep_map)
-
-    def requires(self,extras=()):
-        """List of Requirements needed for this distro if `extras` are used"""
-        dm = self._dep_map
-        deps = []
-        deps.extend(dm.get(None,()))
-        for ext in extras:
-            try:
-                deps.extend(dm[safe_extra(ext)])
-            except KeyError:
-                raise UnknownExtra(
-                    "%s has no such extra feature %r" % (self, ext)
-                )
-        return deps
-
-    def _get_metadata(self,name):
-        if self.has_metadata(name):
-            for line in self.get_metadata_lines(name):
-                yield line
-
-    def activate(self,path=None):
-        """Ensure distribution is importable on `path` (default=sys.path)"""
-        if path is None: path = sys.path
-        self.insert_on(path)
-        if path is sys.path:
-            fixup_namespace_packages(self.location)
-            list(map(declare_namespace, self._get_metadata('namespace_packages.txt')))
-
-
-    def egg_name(self):
-        """Return what this distribution's standard .egg filename should be"""
-        filename = "%s-%s-py%s" % (
-            to_filename(self.project_name), to_filename(self.version),
-            self.py_version or PY_MAJOR
-        )
-
-        if self.platform:
-            filename += '-'+self.platform
-        return filename
-
-    def __repr__(self):
-        if self.location:
-            return "%s (%s)" % (self,self.location)
-        else:
-            return str(self)
-
-    def __str__(self):
-        try: version = getattr(self,'version',None)
-        except ValueError: version = None
-        version = version or "[unknown version]"
-        return "%s %s" % (self.project_name,version)
-
-    def __getattr__(self,attr):
-        """Delegate all unrecognized public attributes to .metadata provider"""
-        if attr.startswith('_'):
-            raise AttributeError(attr)
-        return getattr(self._provider, attr)
-
-    #@classmethod
-    def from_filename(cls,filename,metadata=None, **kw):
-        return cls.from_location(
-            _normalize_cached(filename), os.path.basename(filename), metadata,
-            **kw
-        )
-    from_filename = classmethod(from_filename)
-
-    def as_requirement(self):
-        """Return a ``Requirement`` that matches this distribution exactly"""
-        return Requirement.parse('%s==%s' % (self.project_name, self.version))
-
-    def load_entry_point(self, group, name):
-        """Return the `name` entry point of `group` or raise ImportError"""
-        ep = self.get_entry_info(group,name)
-        if ep is None:
-            raise ImportError("Entry point %r not found" % ((group,name),))
-        return ep.load()
-
-    def get_entry_map(self, group=None):
-        """Return the entry point map for `group`, or the full entry map"""
-        try:
-            ep_map = self._ep_map
-        except AttributeError:
-            ep_map = self._ep_map = EntryPoint.parse_map(
-                self._get_metadata('entry_points.txt'), self
-            )
-        if group is not None:
-            return ep_map.get(group,{})
-        return ep_map
-
-    def get_entry_info(self, group, name):
-        """Return the EntryPoint object for `group`+`name`, or ``None``"""
-        return self.get_entry_map(group).get(name)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    def insert_on(self, path, loc = None):
-        """Insert self.location in path before its nearest parent directory"""
-
-        loc = loc or self.location
-
-        if self.project_name == 'setuptools':
-            try:
-                version = self.version
-            except ValueError:
-                version = ''
-            if '0.7' in version:
-                raise ValueError(
-                    "A 0.7-series setuptools cannot be installed "
-                    "with distribute. Found one at %s" % str(self.location))
-
-        if not loc:
-            return
-
-        if path is sys.path:
-            self.check_version_conflict()
-
-        nloc = _normalize_cached(loc)
-        bdir = os.path.dirname(nloc)
-        npath= list(map(_normalize_cached, path))
-
-        bp = None
-        for p, item in enumerate(npath):
-            if item==nloc:
-                break
-            elif item==bdir and self.precedence==EGG_DIST:
-                # if it's an .egg, give it precedence over its directory
-                path.insert(p, loc)
-                npath.insert(p, nloc)
-                break
-        else:
-            path.append(loc)
-            return
-
-        # p is the spot where we found or inserted loc; now remove duplicates
-        while 1:
-            try:
-                np = npath.index(nloc, p+1)
-            except ValueError:
-                break
-            else:
-                del npath[np], path[np]
-                p = np  # ha!
-
-        return
-
-
-
-    def check_version_conflict(self):
-        if self.key=='distribute':
-            return      # ignore the inevitable setuptools self-conflicts  :(
-
-        nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt'))
-        loc = normalize_path(self.location)
-        for modname in self._get_metadata('top_level.txt'):
-            if (modname not in sys.modules or modname in nsp
-                or modname in _namespace_packages
-            ):
-                continue
-            if modname in ('pkg_resources', 'setuptools', 'site'):
-                continue
-            fn = getattr(sys.modules[modname], '__file__', None)
-            if fn and (normalize_path(fn).startswith(loc) or
-                       fn.startswith(self.location)):
-                continue
-            issue_warning(
-                "Module %s was already imported from %s, but %s is being added"
-                " to sys.path" % (modname, fn, self.location),
-            )
-
-    def has_version(self):
-        try:
-            self.version
-        except ValueError:
-            issue_warning("Unbuilt egg for "+repr(self))
-            return False
-        return True
-
-    def clone(self,**kw):
-        """Copy this distribution, substituting in any changed keyword args"""
-        for attr in (
-            'project_name', 'version', 'py_version', 'platform', 'location',
-            'precedence'
-        ):
-            kw.setdefault(attr, getattr(self,attr,None))
-        kw.setdefault('metadata', self._provider)
-        return self.__class__(**kw)
-
-
-
-
-    #@property
-    def extras(self):
-        return [dep for dep in self._dep_map if dep]
-    extras = property(extras)
-
-
-class DistInfoDistribution(Distribution):
-    """Wrap an actual or potential sys.path entry w/metadata, .dist-info style"""
-    PKG_INFO = 'METADATA'
-    EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])")
-
-    @property
-    def _parsed_pkg_info(self):
-        """Parse and cache metadata"""
-        try:
-            return self._pkg_info
-        except AttributeError:
-            from email.parser import Parser
-            self._pkg_info = Parser().parsestr(self.get_metadata(self.PKG_INFO))
-            return self._pkg_info
-    
-    @property
-    def _dep_map(self):
-        try:
-            return self.__dep_map
-        except AttributeError:
-            self.__dep_map = self._compute_dependencies()
-            return self.__dep_map
-
-    def _preparse_requirement(self, requires_dist):
-        """Convert 'Foobar (1); baz' to ('Foobar ==1', 'baz')
-        Split environment marker, add == prefix to version specifiers as 
-        necessary, and remove parenthesis.
-        """
-        parts = requires_dist.split(';', 1) + ['']
-        distvers = parts[0].strip()
-        mark = parts[1].strip()
-        distvers = re.sub(self.EQEQ, r"\1==\2\3", distvers)
-        distvers = distvers.replace('(', '').replace(')', '')
-        return (distvers, mark)
-            
-    def _compute_dependencies(self):
-        """Recompute this distribution's dependencies."""
-        def dummy_marker(marker):
-            def marker_fn(environment=None, override=None):
-                return True
-            marker_fn.__doc__ = marker
-            return marker_fn
-        try:
-            from markerlib import as_function
-        except ImportError:
-            as_function = dummy_marker
-        dm = self.__dep_map = {None: []}
-
-        reqs = []
-        # Including any condition expressions
-        for req in self._parsed_pkg_info.get_all('Requires-Dist') or []:
-            distvers, mark = self._preparse_requirement(req)
-            parsed = next(parse_requirements(distvers))
-            parsed.marker_fn = as_function(mark)
-            reqs.append(parsed)
-            
-        def reqs_for_extra(extra):
-            for req in reqs:
-                if req.marker_fn(override={'extra':extra}):
-                    yield req
-
-        common = set(reqs_for_extra(None))
-        dm[None].extend(common)
-            
-        for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []:
-            extra = safe_extra(extra.strip())
-            dm[extra] = list(set(reqs_for_extra(extra)) - common)
-
-        return dm
-    
-
-_distributionImpl = {'.egg': Distribution,
-                     '.egg-info': Distribution,
-                     '.dist-info': DistInfoDistribution }
-
-
-def issue_warning(*args,**kw):
-    level = 1
-    g = globals()
-    try:
-        # find the first stack frame that is *not* code in
-        # the pkg_resources module, to use for the warning
-        while sys._getframe(level).f_globals is g:
-            level += 1
-    except ValueError:
-        pass
-    from warnings import warn
-    warn(stacklevel = level+1, *args, **kw)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-def parse_requirements(strs):
-    """Yield ``Requirement`` objects for each specification in `strs`
-
-    `strs` must be an instance of ``basestring``, or a (possibly-nested)
-    iterable thereof.
-    """
-    # create a steppable iterator, so we can handle \-continuations
-    lines = iter(yield_lines(strs))
-
-    def scan_list(ITEM,TERMINATOR,line,p,groups,item_name):
-
-        items = []
-
-        while not TERMINATOR(line,p):
-            if CONTINUE(line,p):
-                try:
-                    line = next(lines); p = 0
-                except StopIteration:
-                    raise ValueError(
-                        "\\ must not appear on the last nonblank line"
-                    )
-
-            match = ITEM(line,p)
-            if not match:
-                raise ValueError("Expected "+item_name+" in",line,"at",line[p:])
-
-            items.append(match.group(*groups))
-            p = match.end()
-
-            match = COMMA(line,p)
-            if match:
-                p = match.end() # skip the comma
-            elif not TERMINATOR(line,p):
-                raise ValueError(
-                    "Expected ',' or end-of-list in",line,"at",line[p:]
-                )
-
-        match = TERMINATOR(line,p)
-        if match: p = match.end()   # skip the terminator, if any
-        return line, p, items
-
-    for line in lines:
-        match = DISTRO(line)
-        if not match:
-            raise ValueError("Missing distribution spec", line)
-        project_name = match.group(1)
-        p = match.end()
-        extras = []
-
-        match = OBRACKET(line,p)
-        if match:
-            p = match.end()
-            line, p, extras = scan_list(
-                DISTRO, CBRACKET, line, p, (1,), "'extra' name"
-            )
-
-        line, p, specs = scan_list(VERSION,LINE_END,line,p,(1,2),"version spec")
-        specs = [(op,safe_version(val)) for op,val in specs]
-        yield Requirement(project_name, specs, extras)
-
-
-def _sort_dists(dists):
-    tmp = [(dist.hashcmp,dist) for dist in dists]
-    tmp.sort()
-    dists[::-1] = [d for hc,d in tmp]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-class Requirement:
-    def __init__(self, project_name, specs, extras):
-        """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
-        self.unsafe_name, project_name = project_name, safe_name(project_name)
-        self.project_name, self.key = project_name, project_name.lower()
-        index = [(parse_version(v),state_machine[op],op,v) for op,v in specs]
-        index.sort()
-        self.specs = [(op,ver) for parsed,trans,op,ver in index]
-        self.index, self.extras = index, tuple(map(safe_extra,extras))
-        self.hashCmp = (
-            self.key, tuple([(op,parsed) for parsed,trans,op,ver in index]),
-            frozenset(self.extras)
-        )
-        self.__hash = hash(self.hashCmp)
-
-    def __str__(self):
-        specs = ','.join([''.join(s) for s in self.specs])
-        extras = ','.join(self.extras)
-        if extras: extras = '[%s]' % extras
-        return '%s%s%s' % (self.project_name, extras, specs)
-
-    def __eq__(self,other):
-        return isinstance(other,Requirement) and self.hashCmp==other.hashCmp
-
-    def __contains__(self,item):
-        if isinstance(item,Distribution):
-            if item.key != self.key: return False
-            if self.index: item = item.parsed_version  # only get if we need it
-        elif isinstance(item,str):
-            item = parse_version(item)
-        last = None
-        compare = lambda a, b: (a > b) - (a < b) # -1, 0, 1
-        for parsed,trans,op,ver in self.index:
-            action = trans[compare(item,parsed)] # Indexing: 0, 1, -1
-            if action=='F':     return False
-            elif action=='T':   return True
-            elif action=='+':   last = True
-            elif action=='-' or last is None:   last = False
-        if last is None: last = True    # no rules encountered
-        return last
-
-
-    def __hash__(self):
-        return self.__hash
-
-    def __repr__(self): return "Requirement.parse(%r)" % str(self)
-
-    #@staticmethod
-    def parse(s, replacement=True):
-        reqs = list(parse_requirements(s))
-        if reqs:
-            if len(reqs) == 1:
-                founded_req = reqs[0]
-                # if asked for setuptools distribution
-                # and if distribute is installed, we want to give
-                # distribute instead
-                if _override_setuptools(founded_req) and replacement:
-                    distribute = list(parse_requirements('distribute'))
-                    if len(distribute) == 1:
-                        return distribute[0]
-                    return founded_req
-                else:
-                    return founded_req
-
-            raise ValueError("Expected only one requirement", s)
-        raise ValueError("No requirements found", s)
-
-    parse = staticmethod(parse)
-
-state_machine = {
-    #       =><
-    '<' :  '--T',
-    '<=':  'T-T',
-    '>' :  'F+F',
-    '>=':  'T+F',
-    '==':  'T..',
-    '!=':  'F++',
-}
-
-
-def _override_setuptools(req):
-    """Return True when distribute wants to override a setuptools dependency.
-
-    We want to override when the requirement is setuptools and the version is
-    a variant of 0.6.
-
-    """
-    if req.project_name == 'setuptools':
-        if not len(req.specs):
-            # Just setuptools: ok
-            return True
-        for comparator, version in req.specs:
-            if comparator in ['==', '>=', '>']:
-                if '0.7' in version:
-                    # We want some setuptools not from the 0.6 series.
-                    return False
-        return True
-    return False
-
-
-def _get_mro(cls):
-    """Get an mro for a type or classic class"""
-    if not isinstance(cls,type):
-        class cls(cls,object): pass
-        return cls.__mro__[1:]
-    return cls.__mro__
-
-def _find_adapter(registry, ob):
-    """Return an adapter factory for `ob` from `registry`"""
-    for t in _get_mro(getattr(ob, '__class__', type(ob))):
-        if t in registry:
-            return registry[t]
-
-
-def ensure_directory(path):
-    """Ensure that the parent directory of `path` exists"""
-    dirname = os.path.dirname(path)
-    if not os.path.isdir(dirname):
-        os.makedirs(dirname)
-
-def split_sections(s):
-    """Split a string or iterable thereof into (section,content) pairs
-
-    Each ``section`` is a stripped version of the section header ("[section]")
-    and each ``content`` is a list of stripped lines excluding blank lines and
-    comment-only lines.  If there are any such lines before the first section
-    header, they're returned in a first ``section`` of ``None``.
-    """
-    section = None
-    content = []
-    for line in yield_lines(s):
-        if line.startswith("["):
-            if line.endswith("]"):
-                if section or content:
-                    yield section, content
-                section = line[1:-1].strip()
-                content = []
-            else:
-                raise ValueError("Invalid section heading", line)
-        else:
-            content.append(line)
-
-    # wrap up last segment
-    yield section, content
-
-def _mkstemp(*args,**kw):
-    from tempfile import mkstemp
-    old_open = os.open
-    try:
-        os.open = os_open   # temporarily bypass sandboxing
-        return mkstemp(*args,**kw)
-    finally:
-        os.open = old_open  # and then put it back
-
-
-# Set up global resource manager (deliberately not state-saved)
-_manager = ResourceManager()
-def _initialize(g):
-    for name in dir(_manager):
-        if not name.startswith('_'):
-            g[name] = getattr(_manager, name)
-_initialize(globals())
-
-# Prepare the master working set and make the ``require()`` API available
-_declare_state('object', working_set = WorkingSet())
-
-try:
-    # Does the main program list any requirements?
-    from __main__ import __requires__
-except ImportError:
-    pass # No: just use the default working set based on sys.path
-else:
-    # Yes: ensure the requirements are met, by prefixing sys.path if necessary
-    try:
-        working_set.require(__requires__)
-    except VersionConflict:     # try it without defaults already on sys.path
-        working_set = WorkingSet([])    # by starting with an empty path
-        for dist in working_set.resolve(
-            parse_requirements(__requires__), Environment()
-        ):
-            working_set.add(dist)
-        for entry in sys.path:  # add any missing entries from sys.path
-            if entry not in working_set.entries:
-                working_set.add_entry(entry)
-        sys.path[:] = working_set.entries   # then copy back to sys.path
-
-require = working_set.require
-iter_entry_points = working_set.iter_entry_points
-add_activation_listener = working_set.subscribe
-run_script = working_set.run_script
-run_main = run_script   # backward compatibility
-# Activate all distributions already on sys.path, and ensure that
-# all distributions added to the working set in the future (e.g. by
-# calling ``require()``) will get activated as well.
-add_activation_listener(lambda dist: dist.activate())
-working_set.entries=[]; list(map(working_set.add_entry,sys.path)) # match order
-
diff --git a/make_perf3.sh b/make_perf3.sh
deleted file mode 100755
--- a/make_perf3.sh
+++ /dev/null
@@ -1,65 +0,0 @@
-#! /usr/bin/env bash
-#
-# NOTE: most benchmarks are natively Python 3-compatible and don't need
-# to be translated.  Simply run perf.py with `-b 2n3` to run them.
-#
-# Usage:
-#   hg clone http://hg.python.org/benchmarks/ py2benchmarks
-#   mkdir py3benchmarks;
-#   cd py3benchmarks
-#   ../py2benchmarks/make_perf3.sh ../py2benchmarks
-#   python3 perf.py -b py3k old_py3k new_py3k
-
-set -e
-
-srcdir=$(cd "$1" && pwd -P)
-
-if [ "x$srcdir" = x ]; then
-    echo "Specify the source directory as the first argument."
-    exit 1
-fi
-if [ "$srcdir" = $(pwd -P) ]; then
-    echo "Can't generate python 3 into the same directory as python 2 version."
-    exit 1
-fi
-
-py3=${PYTHON:-python3}
-
-# Update the files in place.
-CONVERT="${py3} -m lib2to3 --write --nobackups --no-diffs"
-
-rm -rf perf.py* lib performance
-
-cp "${srcdir}/perf.py" perf.py
-${CONVERT} perf.py
-
-# Libraries that are Python 3 compatible as-is.
-SAFE_LIBS_AS_IS="Chameleon-2.9.2 pathlib Django-1.5"
-# Libraries that work with Python 3 after passing through 2to3.
-SAFE_LIBS_TO_TRANSLATE="2to3 mako-0.3.6 Mako-0.7.3"
-# Libraries whose source is Python 3 only.
-SAFE_LIBS_PORTED=""
-
-mkdir lib
-for safe_lib in ${SAFE_LIBS_AS_IS}; do
-  cp -a "${srcdir}/lib/${safe_lib}" lib/${safe_lib}
-done
-
-for safe_lib in ${SAFE_LIBS_TO_TRANSLATE}; do
-  cp -a "${srcdir}/lib/${safe_lib}" lib/${safe_lib}
-  ${CONVERT} lib/${safe_lib}
-done
-
-for safe_lib in ${SAFE_LIBS_PORTED}; do
-  cp -a "${srcdir}/lib3/${safe_lib}" lib/${safe_lib}
-done
-
-# Touch-ups
-cp ${srcdir}/lib3/pkg_resources.py lib/Chameleon-2.9.2/src
-
-cp -a "${srcdir}/performance" performance
-
-# The 2to3 benchmark looks for sample data to run over behind the
-# 2to3_data symlink.  That needs to point to python-2 source, even
-# though we're running 2to3 inside python-3.
-( cd lib; ln -sf "${srcdir}/lib/2to3" 2to3_data )
diff --git a/perf.py b/perf.py
--- a/perf.py
+++ b/perf.py
@@ -87,6 +87,10 @@
 
 info = logging.info
 
+if sys.version_info[0] == 2:
+    ported_lib = 'lib'
+else:
+    ported_lib = 'lib3'
 
 def avg(seq):
     return sum(seq) / float(len(seq))
@@ -1268,8 +1272,8 @@
 
 
 def Measure2to3(python, options):
-    fast_target = Relative("lib/2to3/lib2to3/refactor.py", python, options)
-    two_to_three_bin = Relative("lib/2to3/2to3", python, options)
+    fast_target = Relative(ported_lib+"/2to3/lib2to3/refactor.py", python, options)
+    two_to_three_bin = Relative(ported_lib+"/2to3/2to3", python, options)
     two_to_three_dir = Relative("lib/2to3_data", python, options)
     env = BuildEnv({"PYTHONPATH": two_to_three_dir},
                    inherit_env=options.inherit_env)
@@ -1335,7 +1339,7 @@
 
 def MeasureChameleon(python, options):
     bm_path = Relative("performance/bm_chameleon.py", python, options)
-    lib_path = Relative("lib/Chameleon-2.9.2/src", python, options)
+    lib_path = Relative(ported_lib+"/Chameleon-2.9.2/src", python, options)
     bm_env = {"PYTHONPATH": lib_path}
     return MeasureGeneric(python, options, bm_path, bm_env, iteration_scaling=3)
 
@@ -1503,7 +1507,7 @@
 
 def MeasureMako(python, options):
     bm_path = Relative("performance/bm_mako.py", python, options)
-    mako_path = Relative("lib/mako-0.3.6", python, options)
+    mako_path = Relative(ported_lib+"/mako-0.3.6", python, options)
     bm_env = BuildEnv({"PYTHONPATH": mako_path}, options.inherit_env)
     return MeasureGeneric(python, options, bm_path, bm_env, iteration_scaling=5)
 
@@ -1514,7 +1518,7 @@
 
 def MeasureMakoV2(python, options):
     bm_path = Relative("performance/bm_mako_v2.py", python, options)
-    mako_path = Relative("lib/Mako-0.7.3", python, options)
+    mako_path = Relative(ported_lib+"/Mako-0.7.3", python, options)
     bm_env = BuildEnv({"PYTHONPATH": mako_path}, options.inherit_env)
     return MeasureGeneric(python, options, bm_path, bm_env,
                           iteration_scaling=10)

-- 
Repository URL: http://hg.python.org/benchmarks


More information about the Python-checkins mailing list